diff --git a/AUTHORS b/AUTHORS index f7a11db..d4ec525b 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -255,6 +255,7 @@ Ernesto Mudu <ernesto.mudu@gmail.com> Etienne Laurin <etienne@atnnn.com> Eugene Kim <eugene70kim@gmail.com> +Eugene Sudin <eugene@sudin.pro> Eunseok Oh <fivesilverstone@gmail.com> Evan Peterson <evan.peterson.ep@gmail.com> Evan Wallace <evan.exe@gmail.com> @@ -427,7 +428,6 @@ John Yani <vanuan@gmail.com> John Yoo <nearbyh13@gmail.com> Johnson Lin <johnson.lin@intel.com> -Jon Kunkee <jkunkee@microsoft.com> Jonathan Frazer <listedegarde@gmail.com> Jonathan Garbee <jonathan@garbee.me> Jonathan Hacker <jhacker@arcanefour.com> @@ -496,7 +496,6 @@ Kingshuk Jana <kingshuk.j@samsung.com> Kirill Bobyrev <kirillbobyrev@gmail.com> Kirill Ovchinnikov <kirill.ovchinn@gmail.com> -Kirk Shoop <kirk.shoop@microsoft.com> Klemen Forstnerič <klemen.forstneric@gmail.com> Kodam Nagaraju <k2.nagaraju@samsung.com> Konrad Dzwinel <kdzwinel@gmail.com> @@ -575,7 +574,6 @@ Mathias Bynens <mathias@qiwi.be> Mathieu Meisser <mmeisser@logitech.com> Matt Arpidone <mma.public@gmail.com> -Matt Siembor <msiembor@microsoft.com> Matt Strum <mstrum@amazon.com> Matt Zeunert <matt@mostlystatic.com> Matthew Bauer <mjbauer95@gmail.com> @@ -708,7 +706,6 @@ Radu Stavila <stavila@adobe.com> Radu Velea <radu.velea@intel.com> Rafael Antognolli <rafael.antognolli@intel.com> -Rafael Cintron <rafael.cintron@microsoft.com> Raghavendra Ghatage <r.ghatage@samsung.com> Raghu Ram Nagaraj <r.nagaraj@samsung.com> Rahul Gupta <rahul.g@samsung.com> @@ -732,7 +729,6 @@ Rene Ladan <r.c.ladan@gmail.com> Richard Baranyi <lordprotector@gmail.com> Richard Li <richard.li@intel.com> -Rick James <rickj@microsoft.com> Rijubrata Bhaumik <rijubrata.bhaumik@intel.com> Riku Voipio <riku.voipio@linaro.org> Rob Buis <rob.buis@samsung.com> @@ -780,7 +776,6 @@ Sathish Kuppuswamy <sathish.kuppuswamy@intel.com> Satoshi Matsuzaki <satoshi.matsuzaki@gmail.com> Sayan Nayak <sayan.nayak@samsung.com> -Scott Blomquist <sblom@microsoft.com> Scott D Phillips <scott.d.phillips@intel.com> Sean Bryant <sean@cyberwang.net> Sean DuBois <seaduboi@amazon.com> @@ -885,7 +880,6 @@ Ting Shao <ting.shao@intel.com> Tom Callaway <tcallawa@redhat.com> Tom Harwood <tfh@skip.org> -Tom Tan <Tom.Tan@microsoft.com> Tomas Popela <tomas.popela@gmail.com> Torsten Kurbad <google@tk-webart.de> Trent Willis <trentmwillis@gmail.com> @@ -917,7 +911,6 @@ Wanming Lin <wanming.lin@intel.com> WenSheng He <wensheng.he@samsung.com> Wesley Lancel <wesleylancel@gmail.com> -Wesley Wigham <t-weswig@microsoft.com> Wesley Wigham <wwigham@gmail.com> Will Hirsch <chromium@willhirsch.co.uk> Will Shackleton <w.shackleton@gmail.com> @@ -1018,6 +1011,7 @@ LG Electronics, Inc. <*@lge.com> Loongson Technology Corporation Limited. <*@loongson.cn> Macadamian <*@macadamian.com> +Microsoft <*@microsoft.com> MIPS Technologies, Inc. <*@mips.com> Mozilla Corporation <*@mozilla.com> Neverware Inc. <*@neverware.com>
diff --git a/DEPS b/DEPS index e4968401..ca91a592 100644 --- a/DEPS +++ b/DEPS
@@ -121,11 +121,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': '77e1ccf3cd19ed079a3c590a67f28f0fa1d73511', + 'skia_revision': '428ec1e55c051f5aa1e1b758cb458f88b78f8ecf', # 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': 'fd65a392b935d2ab32423ad6f803e8568e014a8a', + 'v8_revision': 'cdef3415a2805f926e6da2d5da25da678867c821', # 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. @@ -133,7 +133,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': '4638dc9def816e8ee86b09293b8b90519d4a5d9f', + 'angle_revision': '96c11cc7949025b21283483eab0c1e2cc1e73e50', # 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. @@ -145,7 +145,7 @@ # 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': '587891b979df5a7e58897aa702db48806bd90900', + 'pdfium_revision': 'b78a068ced745b72f26b686cf8b3985c4705bd74', # 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. @@ -229,7 +229,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'spv_tools_revision': '9d04f82befe1cbbe21b39e07ab9255d06cb37872', + 'spv_tools_revision': 'e49bd96f2c1e888b5647a8a84e3c4787a62d1d94', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -245,7 +245,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '2745f37875fb0a78e984d9f379df3c493d62613c', + 'dawn_revision': 'c8bf89ddf03e36f610049c0c1b8796b3713e4355', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -679,7 +679,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'bf081d0b4ada31320123d3ab81cd43acce737d0e', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'a73e5af7bb15f669651fee13e4a4d27b46efb574', 'condition': 'checkout_linux', }, @@ -704,7 +704,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '0a8ce8ee8b273bab0b36e5b0f9b981884813c247', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '2cc6e25536698e4f87d516f5242dd9d30d3245ba', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -930,7 +930,7 @@ }, 'src/third_party/libvpx/source/libvpx': - Var('chromium_git') + '/webm/libvpx.git' + '@' + 'd8f89c49e17bec211eaedcf4eeeee4facaaf5513', + Var('chromium_git') + '/webm/libvpx.git' + '@' + '57f7c6f19144786c57d5cfc8e878765bd9944baf', 'src/third_party/libwebm/source': Var('chromium_git') + '/webm/libwebm.git' + '@' + 'e4931ebc0a816458c18a6734e91a4d1b5acd5c56', @@ -1036,7 +1036,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'c041278576ce175bfe12688eddf6c6abf3405cae', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'ee899a100b3f9f06d59738577f0b652f7dc6d530', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1199,7 +1199,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'a2b35635aaef3e9301d69f77f9a0a3fd99291b08', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'aabac232b1a35d73a0f4cbfa7d746a0532bca159', + Var('webrtc_git') + '/src.git' + '@' + '9a4f38ec5c4aa23d24dceb7161c41eb379198f89', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1230,7 +1230,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@534fc360f6c5d274ac513ca1acfe81d8e9c39b5e', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@fd3d56928fcabcbd7745cbc168f3f2b493ed50d4', 'condition': 'checkout_src_internal', },
diff --git a/WATCHLISTS b/WATCHLISTS index 85700e5..acd685a 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -1179,6 +1179,7 @@ }, 'multidevice': { 'filepath': 'ash/multi_device_setup/'\ + '|chrome/browser/chromeos/cryptauth/'\ '|chrome/browser/chromeos/device_sync/'\ '|chrome/browser/chromeos/multidevice_setup/'\ '|chrome/browser/chromeos/secure_channel/'\ @@ -1186,11 +1187,13 @@ '|chrome/browser/resources/settings/multidevice_page/'\ '|chrome/browser/ui/webui/chromeos/multidevice_setup/'\ '|chrome/browser/ui/webui/settings/chromeos/multidevice'\ + '|chrome/test/data/webui/multidevice_setup/'\ + '|chromeos/components/multidevice/'\ '|chromeos/components/proximity_auth/'\ + '|chromeos/resources/multidevice_resources.grdp'\ '|chromeos/services/device_sync/'\ '|chromeos/services/multidevice_setup/'\ '|chromeos/services/secure_channel/'\ - '|components/cryptauth/'\ '|ui/webui/resources/cr_components/chromeos/multidevice_setup/' }, 'mus': {
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index 70af08d1..545d43d 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -55,6 +55,7 @@ "java/src/org/chromium/android_webview/AwMetricsServiceClient.java", "java/src/org/chromium/android_webview/AwPdfExporter.java", "java/src/org/chromium/android_webview/AwPicture.java", + "java/src/org/chromium/android_webview/AwProxyController.java", "java/src/org/chromium/android_webview/AwQuotaManagerBridge.java", "java/src/org/chromium/android_webview/AwRenderProcess.java", "java/src/org/chromium/android_webview/AwResource.java", @@ -524,6 +525,7 @@ "browser/aw_print_manager.h", "browser/aw_printing_message_filter.cc", "browser/aw_printing_message_filter.h", + "browser/aw_proxy_controller.cc", "browser/aw_proxying_url_loader_factory.cc", "browser/aw_proxying_url_loader_factory.h", "browser/aw_quota_manager_bridge.cc", @@ -580,8 +582,6 @@ "browser/deferred_gpu_command_service.h", "browser/find_helper.cc", "browser/find_helper.h", - "browser/gl_view_renderer_manager.cc", - "browser/gl_view_renderer_manager.h", "browser/hardware_renderer.cc", "browser/hardware_renderer.h", "browser/icon_helper.cc", @@ -859,6 +859,7 @@ "java/src/org/chromium/android_webview/AwPdfExporter.java", "java/src/org/chromium/android_webview/AwPicture.java", "java/src/org/chromium/android_webview/AwPrintDocumentAdapter.java", + "java/src/org/chromium/android_webview/AwProxyController.java", "java/src/org/chromium/android_webview/AwSafeBrowsingConfigHelper.java", "java/src/org/chromium/android_webview/AwSafeBrowsingResponse.java", "java/src/org/chromium/android_webview/AwQuotaManagerBridge.java",
diff --git a/android_webview/browser/aw_contents.cc b/android_webview/browser/aw_contents.cc index 1f05a6c..9ebecdcd 100644 --- a/android_webview/browser/aw_contents.cc +++ b/android_webview/browser/aw_contents.cc
@@ -239,8 +239,7 @@ browser_view_renderer_( this, base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI})), - web_contents_(std::move(web_contents)), - renderer_manager_key_(GLViewRendererManager::GetInstance()->NullKey()) { + web_contents_(std::move(web_contents)) { base::subtle::NoBarrier_AtomicIncrement(&g_instance_count, 1); icon_helper_.reset(new IconHelper(web_contents_.get())); icon_helper_->SetListener(this);
diff --git a/android_webview/browser/aw_contents.h b/android_webview/browser/aw_contents.h index 1d7e579..1570655 100644 --- a/android_webview/browser/aw_contents.h +++ b/android_webview/browser/aw_contents.h
@@ -16,7 +16,6 @@ #include "android_webview/browser/browser_view_renderer.h" #include "android_webview/browser/browser_view_renderer_client.h" #include "android_webview/browser/find_helper.h" -#include "android_webview/browser/gl_view_renderer_manager.h" #include "android_webview/browser/icon_helper.h" #include "android_webview/browser/permission/permission_request_handler_client.h" #include "android_webview/browser/renderer_host/aw_render_view_host_ext.h" @@ -394,8 +393,6 @@ // The first element in the list is always the currently pending request. std::list<OriginCallback> pending_geolocation_prompts_; - GLViewRendererManager::Key renderer_manager_key_; - DISALLOW_COPY_AND_ASSIGN(AwContents); };
diff --git a/android_webview/browser/aw_contents_statics.cc b/android_webview/browser/aw_contents_statics.cc index 299881e..e00917f 100644 --- a/android_webview/browser/aw_contents_statics.cc +++ b/android_webview/browser/aw_contents_statics.cc
@@ -10,7 +10,6 @@ #include "base/android/jni_array.h" #include "base/android/jni_string.h" #include "base/android/scoped_java_ref.h" -#include "base/bind.h" #include "base/callback.h" #include "base/task/post_task.h" #include "components/google/core/common/google_util.h" @@ -53,14 +52,6 @@ Java_AwContentsStatics_safeBrowsingWhitelistAssigned(env, callback, success); } -void ProxyOverrideChanged(const JavaRef<jobject>& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (callback.is_null()) - return; - JNIEnv* env = AttachCurrentThread(); - Java_AwContentsStatics_proxyOverrideChanged(env, callback); -} - } // namespace // static @@ -133,31 +124,4 @@ AwURLRequestContextGetter::set_check_cleartext_permitted(permitted); } -// static -void JNI_AwContentsStatics_SetProxyOverride( - JNIEnv* env, - const base::android::JavaParamRef<jstring>& jhost, - jint port, - const base::android::JavaParamRef<jobjectArray>& jexclusion_list, - const JavaParamRef<jobject>& callback) { - std::string host; - base::android::ConvertJavaStringToUTF8(env, jhost, &host); - std::vector<std::string> exclusion_list; - base::android::AppendJavaStringArrayToStringVector(env, jexclusion_list, - &exclusion_list); - AwBrowserContext::GetDefault()->GetAwURLRequestContext()->SetProxyOverride( - host, port, exclusion_list, - base::BindOnce(&ProxyOverrideChanged, - ScopedJavaGlobalRef<jobject>(env, callback))); -} - -// static -void JNI_AwContentsStatics_ClearProxyOverride( - JNIEnv* env, - const JavaParamRef<jobject>& callback) { - AwBrowserContext::GetDefault()->GetAwURLRequestContext()->ClearProxyOverride( - base::BindOnce(&ProxyOverrideChanged, - ScopedJavaGlobalRef<jobject>(env, callback))); -} - } // namespace android_webview
diff --git a/android_webview/browser/aw_proxy_controller.cc b/android_webview/browser/aw_proxy_controller.cc new file mode 100644 index 0000000..add6746b --- /dev/null +++ b/android_webview/browser/aw_proxy_controller.cc
@@ -0,0 +1,96 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "android_webview/browser/aw_browser_context.h" +#include "android_webview/browser/net/aw_url_request_context_getter.h" +#include "base/android/jni_array.h" +#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "base/bind.h" +#include "base/callback.h" +#include "base/message_loop/message_loop_current.h" +#include "content/public/browser/browser_thread.h" +#include "jni/AwProxyController_jni.h" +#include "net/proxy_resolution/proxy_config_service_android.h" + +using base::android::AttachCurrentThread; +using base::android::HasException; +using base::android::JavaParamRef; +using base::android::JavaRef; +using base::android::ScopedJavaGlobalRef; +using base::android::ScopedJavaLocalRef; +using content::BrowserThread; + +namespace android_webview { + +namespace { + +void ProxyOverrideChanged(const JavaRef<jobject>& obj, + const JavaRef<jobject>& listener, + const JavaRef<jobject>& executor) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (listener.is_null()) + return; + JNIEnv* env = AttachCurrentThread(); + Java_AwProxyController_proxyOverrideChanged(env, obj, listener, executor); + if (HasException(env)) { + // Tell the chromium message loop to not perform any tasks after the current + // one - we want to make sure we return to Java cleanly without first making + // any new JNI calls. + base::MessageLoopCurrentForUI::Get()->Abort(); + } +} + +} // namespace + +ScopedJavaLocalRef<jstring> JNI_AwProxyController_SetProxyOverride( + JNIEnv* env, + const JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jobjectArray>& jurl_schemes, + const base::android::JavaParamRef<jobjectArray>& jproxy_urls, + const base::android::JavaParamRef<jobjectArray>& jbypass_rules, + const JavaParamRef<jobject>& listener, + const JavaParamRef<jobject>& executor) { + std::vector<std::string> url_schemes; + base::android::AppendJavaStringArrayToStringVector(env, jurl_schemes, + &url_schemes); + std::vector<std::string> proxy_urls; + base::android::AppendJavaStringArrayToStringVector(env, jproxy_urls, + &proxy_urls); + std::vector<net::ProxyConfigServiceAndroid::ProxyOverrideRule> proxy_rules; + int size = url_schemes.size(); + DCHECK(url_schemes.size() == proxy_urls.size()); + proxy_rules.reserve(size); + for (int i = 0; i < size; i++) { + proxy_rules.emplace_back(url_schemes[i], proxy_urls[i]); + } + std::vector<std::string> bypass_rules; + base::android::AppendJavaStringArrayToStringVector(env, jbypass_rules, + &bypass_rules); + + std::string result = + AwBrowserContext::GetDefault() + ->GetAwURLRequestContext() + ->SetProxyOverride( + proxy_rules, bypass_rules, + base::BindOnce(&ProxyOverrideChanged, + ScopedJavaGlobalRef<jobject>(env, obj), + ScopedJavaGlobalRef<jobject>(env, listener), + ScopedJavaGlobalRef<jobject>(env, executor))); + return base::android::ConvertUTF8ToJavaString(env, result); +} + +void JNI_AwProxyController_ClearProxyOverride( + JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jobject>& listener, + const JavaParamRef<jobject>& executor) { + AwBrowserContext::GetDefault()->GetAwURLRequestContext()->ClearProxyOverride( + base::BindOnce(&ProxyOverrideChanged, + ScopedJavaGlobalRef<jobject>(env, obj), + ScopedJavaGlobalRef<jobject>(env, listener), + ScopedJavaGlobalRef<jobject>(env, executor))); +} + +} // namespace android_webview \ No newline at end of file
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc index 055c042d..182c67e 100644 --- a/android_webview/browser/browser_view_renderer.cc +++ b/android_webview/browser/browser_view_renderer.cc
@@ -209,8 +209,6 @@ DCHECK(current_compositor_frame_consumer_); TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDrawHardware"); - current_compositor_frame_consumer_->InitializeHardwareDrawIfNeededOnUI(); - if (!CanOnDraw()) { return false; }
diff --git a/android_webview/browser/compositor_frame_consumer.h b/android_webview/browser/compositor_frame_consumer.h index 4990301..2a65329a 100644 --- a/android_webview/browser/compositor_frame_consumer.h +++ b/android_webview/browser/compositor_frame_consumer.h
@@ -42,7 +42,6 @@ // Returns uncommitted frame to be returned, if any. virtual std::unique_ptr<ChildFrame> SetFrameOnUI( std::unique_ptr<ChildFrame> frame) = 0; - virtual void InitializeHardwareDrawIfNeededOnUI() = 0; virtual ParentCompositorDrawConstraints GetParentDrawConstraintsOnUI() const = 0; virtual void SwapReturnedResourcesOnUI(
diff --git a/android_webview/browser/deferred_gpu_command_service.cc b/android_webview/browser/deferred_gpu_command_service.cc index c645f864..056072e 100644 --- a/android_webview/browser/deferred_gpu_command_service.cc +++ b/android_webview/browser/deferred_gpu_command_service.cc
@@ -4,13 +4,12 @@ #include "android_webview/browser/deferred_gpu_command_service.h" -#include "android_webview/browser/gl_view_renderer_manager.h" #include "android_webview/browser/render_thread_manager.h" +#include "base/auto_reset.h" #include "base/command_line.h" #include "base/lazy_instance.h" #include "base/no_destructor.h" #include "base/strings/string_number_conversions.h" -#include "base/synchronization/lock.h" #include "base/trace_event/trace_event.h" #include "content/public/browser/gpu_data_manager.h" #include "content/public/browser/gpu_utils.h" @@ -39,18 +38,16 @@ DeferredGpuCommandService* service = DeferredGpuCommandService::GetInstance(); DCHECK(service); - service->RunTasks(); + DCHECK(!service->HasMoreTasks()); } ScopedAllowGL::~ScopedAllowGL() { - allow_gl.Get().Set(false); - DeferredGpuCommandService* service = DeferredGpuCommandService::GetInstance(); DCHECK(service); service->RunTasks(); - if (service->IdleQueueSize()) { - service->RequestProcessGL(true); - } + service->PerformAllIdleWork(); + DCHECK(!service->HasMoreTasks()); + allow_gl.Get().Set(false); } // gpu::CommandBufferTaskExectuor::Sequence implementation that encapsulates a @@ -159,45 +156,25 @@ nullptr, gl::GLSurfaceFormat()), sync_point_manager_(std::move(sync_point_manager)), - gpu_info_(gpu_info) {} - -DeferredGpuCommandService::~DeferredGpuCommandService() { - base::AutoLock lock(tasks_lock_); - DCHECK(tasks_.empty()); + gpu_info_(gpu_info) { + DETACH_FROM_THREAD(task_queue_thread_checker_); } -// This method can be called on any thread. -// static -void DeferredGpuCommandService::RequestProcessGL(bool for_idle) { - RenderThreadManager* renderer_state = - GLViewRendererManager::GetInstance()->GetMostRecentlyDrawn(); - if (!renderer_state) { - LOG(ERROR) << "No hardware renderer. Deadlock likely"; - return; - } - renderer_state->ClientRequestInvokeGL(for_idle); +DeferredGpuCommandService::~DeferredGpuCommandService() { + DCHECK(tasks_.empty()); } // Called from different threads! void DeferredGpuCommandService::ScheduleTask(base::OnceClosure task, bool out_of_order) { - { - base::AutoLock lock(tasks_lock_); - if (out_of_order) - tasks_.emplace_front(std::move(task)); - else - tasks_.emplace_back(std::move(task)); - } - if (ScopedAllowGL::IsAllowed()) { - RunTasks(); - } else { - RequestProcessGL(false); - } -} - -size_t DeferredGpuCommandService::IdleQueueSize() { - base::AutoLock lock(tasks_lock_); - return idle_tasks_.size(); + DCHECK_CALLED_ON_VALID_THREAD(task_queue_thread_checker_); + LOG_IF(FATAL, !ScopedAllowGL::IsAllowed()) + << "ScheduleTask outside of ScopedAllowGL"; + if (out_of_order) + tasks_.emplace_front(std::move(task)); + else + tasks_.emplace_back(std::move(task)); + RunTasks(); } std::unique_ptr<gpu::CommandBufferTaskExecutor::Sequence> @@ -211,44 +188,23 @@ void DeferredGpuCommandService::ScheduleDelayedWork( base::OnceClosure callback) { - { - base::AutoLock lock(tasks_lock_); - idle_tasks_.push(std::make_pair(base::Time::Now(), std::move(callback))); - } - RequestProcessGL(true); -} - -void DeferredGpuCommandService::PerformIdleWork(bool is_idle) { - TRACE_EVENT1("android_webview", "DeferredGpuCommandService::PerformIdleWork", - "is_idle", is_idle); - DCHECK(ScopedAllowGL::IsAllowed()); - static const base::TimeDelta kMaxIdleAge = - base::TimeDelta::FromMilliseconds(16); - - const base::Time now = base::Time::Now(); - size_t queue_size = IdleQueueSize(); - while (queue_size--) { - base::OnceClosure task; - { - base::AutoLock lock(tasks_lock_); - if (!is_idle) { - // Only run old tasks if we are not really idle right now. - base::TimeDelta age(now - idle_tasks_.front().first); - if (age < kMaxIdleAge) - break; - } - task = std::move(idle_tasks_.front().second); - idle_tasks_.pop(); - } - std::move(task).Run(); - } + LOG_IF(FATAL, !ScopedAllowGL::IsAllowed()) + << "ScheduleDelayedWork outside of ScopedAllowGL"; + DCHECK_CALLED_ON_VALID_THREAD(task_queue_thread_checker_); + idle_tasks_.push(std::make_pair(base::Time::Now(), std::move(callback))); } void DeferredGpuCommandService::PerformAllIdleWork() { TRACE_EVENT0("android_webview", "DeferredGpuCommandService::PerformAllIdleWork"); - while (IdleQueueSize()) { - PerformIdleWork(true); + DCHECK_CALLED_ON_VALID_THREAD(task_queue_thread_checker_); + if (inside_run_idle_tasks_) + return; + base::AutoReset<bool> inside(&inside_run_idle_tasks_, true); + while (idle_tasks_.size()) { + base::OnceClosure task = std::move(idle_tasks_.front().second); + idle_tasks_.pop(); + std::move(task).Run(); } } @@ -262,25 +218,19 @@ void DeferredGpuCommandService::RunTasks() { TRACE_EVENT0("android_webview", "DeferredGpuCommandService::RunTasks"); - bool has_more_tasks; - { - base::AutoLock lock(tasks_lock_); - has_more_tasks = tasks_.size() > 0; + DCHECK_CALLED_ON_VALID_THREAD(task_queue_thread_checker_); + if (inside_run_tasks_) + return; + base::AutoReset<bool> inside(&inside_run_tasks_, true); + while (tasks_.size()) { + std::move(tasks_.front()).Run(); + tasks_.pop_front(); } +} - while (has_more_tasks) { - base::OnceClosure task; - { - base::AutoLock lock(tasks_lock_); - task = std::move(tasks_.front()); - tasks_.pop_front(); - } - std::move(task).Run(); - { - base::AutoLock lock(tasks_lock_); - has_more_tasks = tasks_.size() > 0; - } - } +bool DeferredGpuCommandService::HasMoreTasks() { + DCHECK_CALLED_ON_VALID_THREAD(task_queue_thread_checker_); + return tasks_.size() || idle_tasks_.size(); } bool DeferredGpuCommandService::CanSupportThreadedTextureMailbox() const {
diff --git a/android_webview/browser/deferred_gpu_command_service.h b/android_webview/browser/deferred_gpu_command_service.h index 0a84ddf..048ab8d 100644 --- a/android_webview/browser/deferred_gpu_command_service.h +++ b/android_webview/browser/deferred_gpu_command_service.h
@@ -13,6 +13,7 @@ #include "base/containers/queue.h" #include "base/lazy_instance.h" #include "base/macros.h" +#include "base/threading/thread_checker.h" #include "base/threading/thread_local.h" #include "base/time/time.h" #include "gpu/config/gpu_info.h" @@ -58,14 +59,6 @@ bool CanSupportThreadedTextureMailbox() const; - // If |is_idle| is false, this will only run older idle tasks. - void PerformIdleWork(bool is_idle); - - // Flush the idle queue until it is empty. This is different from - // PerformIdleWork(is_idle = true), which does not run any newly scheduled - // idle tasks during the idle run. - void PerformAllIdleWork(); - protected: ~DeferredGpuCommandService() override; @@ -73,8 +66,6 @@ friend class ScopedAllowGL; friend class TaskForwardingSequence; - static void RequestProcessGL(bool for_idle); - DeferredGpuCommandService( std::unique_ptr<gpu::SyncPointManager> sync_point_manager, const gpu::GpuPreferences& gpu_preferences, @@ -83,19 +74,26 @@ static DeferredGpuCommandService* CreateDeferredGpuCommandService(); - size_t IdleQueueSize(); + // Flush the idle queue until it is empty. + void PerformAllIdleWork(); // Called by ScopedAllowGL and ScheduleTask(). void RunTasks(); + bool HasMoreTasks(); + // Called by TaskForwardingSequence. |out_of_order| indicates if task should // be run ahead of already enqueued tasks. void ScheduleTask(base::OnceClosure task, bool out_of_order); - base::Lock tasks_lock_; + // All access to task queue should happen on a single thread. + THREAD_CHECKER(task_queue_thread_checker_); base::circular_deque<base::OnceClosure> tasks_; base::queue<std::pair<base::Time, base::OnceClosure>> idle_tasks_; + bool inside_run_tasks_ = false; + bool inside_run_idle_tasks_ = false; + std::unique_ptr<gpu::SyncPointManager> sync_point_manager_; gpu::GPUInfo gpu_info_;
diff --git a/android_webview/browser/gl_view_renderer_manager.cc b/android_webview/browser/gl_view_renderer_manager.cc deleted file mode 100644 index 750846a..0000000 --- a/android_webview/browser/gl_view_renderer_manager.cc +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2013 The Chromium 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 "android_webview/browser/gl_view_renderer_manager.h" - -#include "base/logging.h" -#include "base/stl_util.h" -#include "base/threading/platform_thread.h" - -namespace android_webview { - -using base::AutoLock; - -namespace { -base::LazyInstance<GLViewRendererManager>::Leaky g_view_renderer_manager = - LAZY_INSTANCE_INITIALIZER; -} // namespace - -// static -GLViewRendererManager* GLViewRendererManager::GetInstance() { - return g_view_renderer_manager.Pointer(); -} - -GLViewRendererManager::GLViewRendererManager() {} - -GLViewRendererManager::~GLViewRendererManager() {} - -GLViewRendererManager::Key GLViewRendererManager::NullKey() { - AutoLock auto_lock(lock_); - return mru_list_.end(); -} - -GLViewRendererManager::Key GLViewRendererManager::PushBack(RendererType view) { - AutoLock auto_lock(lock_); - DCHECK(!base::ContainsValue(mru_list_, view)); - mru_list_.push_back(view); - Key back = mru_list_.end(); - back--; - return back; -} - -void GLViewRendererManager::DidDrawGL(Key key) { - AutoLock auto_lock(lock_); - DCHECK(mru_list_.end() != key); - mru_list_.splice(mru_list_.begin(), mru_list_, key); -} - -void GLViewRendererManager::Remove(Key key) { - AutoLock auto_lock(lock_); - DCHECK(mru_list_.end() != key); - mru_list_.erase(key); -} - -GLViewRendererManager::RendererType -GLViewRendererManager::GetMostRecentlyDrawn() const { - AutoLock auto_lock(lock_); - if (mru_list_.begin() == mru_list_.end()) - return NULL; - return *mru_list_.begin(); -} - -} // namespace android_webview
diff --git a/android_webview/browser/gl_view_renderer_manager.h b/android_webview/browser/gl_view_renderer_manager.h deleted file mode 100644 index 785f3bef..0000000 --- a/android_webview/browser/gl_view_renderer_manager.h +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2013 The Chromium 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 ANDROID_WEBVIEW_BROWSER_GL_VIEW_RENDERER_MANAGER_H_ -#define ANDROID_WEBVIEW_BROWSER_GL_VIEW_RENDERER_MANAGER_H_ - -#include <list> - -#include "base/lazy_instance.h" -#include "base/macros.h" -#include "base/synchronization/lock.h" -#include "base/threading/platform_thread.h" - -namespace android_webview { - -class RenderThreadManager; - -class GLViewRendererManager { - public: - typedef RenderThreadManager* RendererType; - - private: - typedef std::list<RendererType> ListType; - - public: - typedef ListType::iterator Key; - - static GLViewRendererManager* GetInstance(); - - Key NullKey(); - - Key PushBack(RendererType view); - - // |key| must be already in manager. Move renderer corresponding to |key| to - // most recent. - void DidDrawGL(Key key); - - void Remove(Key key); - - RendererType GetMostRecentlyDrawn() const; - - private: - friend struct base::LazyInstanceTraitsBase<GLViewRendererManager>; - - GLViewRendererManager(); - ~GLViewRendererManager(); - - mutable base::Lock lock_; - ListType mru_list_; - - DISALLOW_COPY_AND_ASSIGN(GLViewRendererManager); -}; - -} // namespace android_webview - -#endif // ANDROID_WEBVIEW_BROWSER_GL_VIEW_RENDERER_MANAGER_H_
diff --git a/android_webview/browser/net/aw_url_request_context_getter.cc b/android_webview/browser/net/aw_url_request_context_getter.cc index d664741..02791cb 100644 --- a/android_webview/browser/net/aw_url_request_context_getter.cc +++ b/android_webview/browser/net/aw_url_request_context_getter.cc
@@ -191,7 +191,7 @@ channel_id_path_(channel_id_path), net_log_(net_log), proxy_config_service_(std::move(config_service)), - proxy_config_service_android_(nullptr), + proxy_config_service_android_(proxy_config_service_.get()), http_user_agent_settings_(new AwHttpUserAgentSettings()) { // CreateSystemProxyConfigService for Android must be called on main thread. DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -292,9 +292,6 @@ net::ProxyResolutionService::CreateFixed(net::ProxyConfigWithAnnotation( proxy_config, NO_TRAFFIC_ANNOTATION_YET))); } else { - // Retain a pointer to the config proxy service before ownership is passed - // on. - proxy_config_service_android_ = proxy_config_service_.get(); builder.set_proxy_resolution_service( net::ProxyResolutionService::CreateWithoutProxyResolver( std::move(proxy_config_service_), net_log_)); @@ -414,21 +411,19 @@ auth_android_negotiate_account_type_.GetValue()); } -void AwURLRequestContextGetter::SetProxyOverride( - const std::string& host, - int port, - const std::vector<std::string>& exclusion_list, +std::string AwURLRequestContextGetter::SetProxyOverride( + const std::vector<net::ProxyConfigServiceAndroid::ProxyOverrideRule>& + proxy_rules, + const std::vector<std::string>& bypass_rules, base::OnceClosure callback) { - if (proxy_config_service_android_ != NULL) { - proxy_config_service_android_->SetProxyOverride(host, port, exclusion_list, - std::move(callback)); - } + DCHECK(proxy_config_service_android_ != nullptr); + return proxy_config_service_android_->SetProxyOverride( + proxy_rules, bypass_rules, std::move(callback)); } void AwURLRequestContextGetter::ClearProxyOverride(base::OnceClosure callback) { - if (proxy_config_service_android_ != NULL) { - proxy_config_service_android_->ClearProxyOverride(std::move(callback)); - } + DCHECK(proxy_config_service_android_ != nullptr); + proxy_config_service_android_->ClearProxyOverride(std::move(callback)); } } // namespace android_webview
diff --git a/android_webview/browser/net/aw_url_request_context_getter.h b/android_webview/browser/net/aw_url_request_context_getter.h index 117bdba..208b2987 100644 --- a/android_webview/browser/net/aw_url_request_context_getter.h +++ b/android_webview/browser/net/aw_url_request_context_getter.h
@@ -13,6 +13,7 @@ #include "base/single_thread_task_runner.h" #include "components/prefs/pref_member.h" #include "content/public/browser/browser_context.h" +#include "net/proxy_resolution/proxy_config_service_android.h" #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_job_factory.h" @@ -52,10 +53,11 @@ const override; // Methods to set and clear proxy override - void SetProxyOverride(const std::string& host, - int port, - const std::vector<std::string>& exclusion_list, - base::OnceClosure callback); + std::string SetProxyOverride( + const std::vector<net::ProxyConfigServiceAndroid::ProxyOverrideRule>& + proxy_rules, + const std::vector<std::string>& bypass_rules, + base::OnceClosure callback); void ClearProxyOverride(base::OnceClosure callback); private:
diff --git a/android_webview/browser/render_thread_manager.cc b/android_webview/browser/render_thread_manager.cc index 7233bfe5..51e070f5 100644 --- a/android_webview/browser/render_thread_manager.cc +++ b/android_webview/browser/render_thread_manager.cc
@@ -24,71 +24,7 @@ namespace android_webview { -namespace internal { - -class RequestInvokeGLTracker { - public: - RequestInvokeGLTracker(); - bool ShouldRequestOnNonUiThread(RenderThreadManager* state); - bool ShouldRequestOnUiThread(RenderThreadManager* state); - void ResetPending(); - void SetQueuedFunctorOnUi(RenderThreadManager* state); - - private: - base::Lock lock_; - RenderThreadManager* pending_ui_; - RenderThreadManager* pending_non_ui_; -}; - -RequestInvokeGLTracker::RequestInvokeGLTracker() - : pending_ui_(NULL), pending_non_ui_(NULL) {} - -bool RequestInvokeGLTracker::ShouldRequestOnNonUiThread( - RenderThreadManager* state) { - base::AutoLock lock(lock_); - if (pending_ui_ || pending_non_ui_) - return false; - pending_non_ui_ = state; - return true; -} - -bool RequestInvokeGLTracker::ShouldRequestOnUiThread( - RenderThreadManager* state) { - base::AutoLock lock(lock_); - if (pending_non_ui_) { - pending_non_ui_->ResetRequestInvokeGLCallback(); - pending_non_ui_ = NULL; - } - // At this time, we could have already called RequestInvokeGL on the UI - // thread, - // but the corresponding GL mode process hasn't happened yet. In this case, - // don't schedule another requestInvokeGL on the UI thread. - if (pending_ui_) - return false; - pending_ui_ = state; - return true; -} - -void RequestInvokeGLTracker::ResetPending() { - base::AutoLock lock(lock_); - pending_non_ui_ = NULL; - pending_ui_ = NULL; -} - -void RequestInvokeGLTracker::SetQueuedFunctorOnUi(RenderThreadManager* state) { - base::AutoLock lock(lock_); - DCHECK(state); - pending_ui_ = state; - pending_non_ui_ = NULL; -} - -} // namespace internal - namespace { - -base::LazyInstance<internal::RequestInvokeGLTracker>::DestructorAtExit - g_request_invoke_gl_tracker = LAZY_INSTANCE_INITIALIZER; - constexpr base::TimeDelta kSlightlyMoreThanOneFrame = base::TimeDelta::FromMilliseconds(17); } @@ -100,13 +36,11 @@ client_(client), compositor_frame_producer_(nullptr), has_received_frame_(false), - renderer_manager_key_(GLViewRendererManager::GetInstance()->NullKey()), inside_hardware_release_(false), weak_factory_on_ui_thread_(this) { DCHECK(ui_loop_->BelongsToCurrentThread()); DCHECK(client_); ui_thread_weak_ptr_ = weak_factory_on_ui_thread_.GetWeakPtr(); - ResetRequestInvokeGLCallback(); } RenderThreadManager::~RenderThreadManager() { @@ -117,50 +51,6 @@ DCHECK(!hardware_renderer_.get()); } -void RenderThreadManager::ClientRequestInvokeGL(bool for_idle) { - if (ui_loop_->BelongsToCurrentThread()) { - if (!g_request_invoke_gl_tracker.Get().ShouldRequestOnUiThread(this)) - return; - ClientRequestInvokeGLOnUI(); - } else { - if (!g_request_invoke_gl_tracker.Get().ShouldRequestOnNonUiThread(this)) - return; - base::OnceClosure callback; - { - base::AutoLock lock(lock_); - callback = request_draw_gl_closure_; - } - // 17ms is slightly longer than a frame, hoping that it will come - // after the next frame so that the idle work is taken care of by - // the next frame instead. - ui_loop_->PostDelayedTask( - FROM_HERE, std::move(callback), - for_idle ? kSlightlyMoreThanOneFrame : base::TimeDelta()); - } -} - -void RenderThreadManager::DidInvokeGLProcess() { - g_request_invoke_gl_tracker.Get().ResetPending(); -} - -void RenderThreadManager::ResetRequestInvokeGLCallback() { - DCHECK(ui_loop_->BelongsToCurrentThread()); - base::AutoLock lock(lock_); - request_draw_gl_cancelable_closure_.Reset(base::BindRepeating( - &RenderThreadManager::ClientRequestInvokeGLOnUI, base::Unretained(this))); - request_draw_gl_closure_ = request_draw_gl_cancelable_closure_.callback(); -} - -void RenderThreadManager::ClientRequestInvokeGLOnUI() { - DCHECK(ui_loop_->BelongsToCurrentThread()); - ResetRequestInvokeGLCallback(); - g_request_invoke_gl_tracker.Get().SetQueuedFunctorOnUi(this); - if (!client_->RequestInvokeGL(false)) { - g_request_invoke_gl_tracker.Get().ResetPending(); - LOG(ERROR) << "Failed to request GL process. Deadlock likely"; - } -} - void RenderThreadManager::UpdateParentDrawConstraintsOnUI() { DCHECK(ui_loop_->BelongsToCurrentThread()); if (compositor_frame_producer_) { @@ -315,24 +205,6 @@ // Force GL binding init if it's not yet initialized. DeferredGpuCommandService::GetInstance(); - // kModeProcessNoContext should never happen because we tear down hardware - // in onTrimMemory. However that guarantee is maintained outside of chromium - // code. Not notifying shared state in kModeProcessNoContext can lead to - // immediate deadlock, which is slightly more catastrophic than leaks or - // corruption. - if (draw_info->mode == AwDrawGLInfo::kModeProcess || - draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) { - DidInvokeGLProcess(); - } - - { - GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); - base::AutoLock lock(lock_); - if (renderer_manager_key_ != manager->NullKey()) { - manager->DidDrawGL(renderer_manager_key_); - } - } - ScopedAppGLStateRestore state_restore( draw_info->mode == AwDrawGLInfo::kModeDraw ? ScopedAppGLStateRestore::MODE_DRAW @@ -351,21 +223,13 @@ if (IsInsideHardwareRelease()) { hardware_renderer_.reset(); - // Flush the idle queue in tear down. - DeferredGpuCommandService::GetInstance()->PerformAllIdleWork(); return; } - if (draw_info->mode != AwDrawGLInfo::kModeDraw) { - if (draw_info->mode == AwDrawGLInfo::kModeProcess) { - DeferredGpuCommandService::GetInstance()->PerformIdleWork(true); - } + if (draw_info->mode != AwDrawGLInfo::kModeDraw) return; - } - if (hardware_renderer_) hardware_renderer_->DrawGL(draw_info); - DeferredGpuCommandService::GetInstance()->PerformIdleWork(false); } void RenderThreadManager::DeleteHardwareRendererOnUI() { @@ -391,21 +255,6 @@ } } - GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); - - { - base::AutoLock lock(lock_); - if (renderer_manager_key_ != manager->NullKey()) { - manager->Remove(renderer_manager_key_); - renderer_manager_key_ = manager->NullKey(); - } - } - - if (has_received_frame_) { - // Flush any invoke functors that's caused by ReleaseHardware. - client_->RequestInvokeGL(true); - } - has_received_frame_ = false; } @@ -422,16 +271,6 @@ return !child_frames_.empty(); } -void RenderThreadManager::InitializeHardwareDrawIfNeededOnUI() { - DCHECK(ui_loop_->BelongsToCurrentThread()); - GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); - - base::AutoLock lock(lock_); - if (renderer_manager_key_ == manager->NullKey()) { - renderer_manager_key_ = manager->PushBack(this); - } -} - RenderThreadManager::InsideHardwareReleaseReset::InsideHardwareReleaseReset( RenderThreadManager* render_thread_manager) : render_thread_manager_(render_thread_manager) {
diff --git a/android_webview/browser/render_thread_manager.h b/android_webview/browser/render_thread_manager.h index 909e16f..16d145b 100644 --- a/android_webview/browser/render_thread_manager.h +++ b/android_webview/browser/render_thread_manager.h
@@ -8,9 +8,7 @@ #include <map> #include "android_webview/browser/compositor_frame_consumer.h" -#include "android_webview/browser/gl_view_renderer_manager.h" #include "android_webview/browser/parent_compositor_draw_constraints.h" -#include "base/cancelable_callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" @@ -20,10 +18,6 @@ struct AwDrawGLInfo; namespace android_webview { -namespace internal { -class RequestInvokeGLTracker; -} - class RenderThreadManagerClient; class ChildFrame; class CompositorFrameProducer; @@ -39,16 +33,12 @@ const scoped_refptr<base::SingleThreadTaskRunner>& ui_loop); ~RenderThreadManager() override; - // This function can be called from any thread. - void ClientRequestInvokeGL(bool for_idle); - // CompositorFrameConsumer methods. void SetCompositorFrameProducer( CompositorFrameProducer* compositor_frame_producer) override; void SetScrollOffsetOnUI(gfx::Vector2d scroll_offset) override; std::unique_ptr<ChildFrame> SetFrameOnUI( std::unique_ptr<ChildFrame> frame) override; - void InitializeHardwareDrawIfNeededOnUI() override; ParentCompositorDrawConstraints GetParentDrawConstraintsOnUI() const override; void SwapReturnedResourcesOnUI( ReturnedResourcesMap* returned_resource_map) override; @@ -68,7 +58,6 @@ uint32_t layer_tree_frame_sink_id); private: - friend class internal::RequestInvokeGLTracker; class InsideHardwareReleaseReset { public: explicit InsideHardwareReleaseReset( @@ -83,12 +72,9 @@ std::unique_ptr<ChildFrame> child_frame); // RT thread method. - void DidInvokeGLProcess(); bool HasFrameForHardwareRendererOnRT() const; // UI thread methods. - void ResetRequestInvokeGLCallback(); - void ClientRequestInvokeGLOnUI(); void UpdateParentDrawConstraintsOnUI(); void ReturnedResourceAvailableOnUI(); bool IsInsideHardwareRelease() const; @@ -99,7 +85,6 @@ RenderThreadManagerClient* const client_; CompositorFrameProducer* compositor_frame_producer_; base::WeakPtr<RenderThreadManager> ui_thread_weak_ptr_; - base::CancelableClosure request_draw_gl_cancelable_closure_; // Whether any frame has been received on the UI thread by // RenderThreadManager. bool has_received_frame_; @@ -107,9 +92,6 @@ // Accessed by RT thread. std::unique_ptr<HardwareRenderer> hardware_renderer_; - // This is accessed by both UI and RT now. TODO(hush): move to RT only. - GLViewRendererManager::Key renderer_manager_key_; - // Accessed by both UI and RT thread. mutable base::Lock lock_; gfx::Vector2d scroll_offset_; @@ -118,7 +100,6 @@ ParentCompositorDrawConstraints parent_draw_constraints_; bool returned_resource_available_pending_ = false; ReturnedResourcesMap returned_resources_map_; - base::RepeatingClosure request_draw_gl_closure_; base::WeakPtrFactory<RenderThreadManager> weak_factory_on_ui_thread_;
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/SharedStatics.java b/android_webview/glue/java/src/com/android/webview/chromium/SharedStatics.java index e53e92dc..3a9cc34b 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/SharedStatics.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/SharedStatics.java
@@ -116,23 +116,4 @@ return ThreadUtils.runOnUiThreadBlockingNoException( () -> AwContentsStatics.getSafeBrowsingPrivacyPolicyUrl()); } - - public void setProxyOverride(String host, int port, String[] exclusionList, Runnable callback) { - if (host == null) { - throw new NullPointerException("Host string should not be null"); - } - if (exclusionList != null) { - for (String url : exclusionList) { - if (url == null) { - throw new NullPointerException("Excluded URL strings should not be null"); - } - } - } - ThreadUtils.runOnUiThread( - () -> AwContentsStatics.setProxyOverride(host, port, exclusionList, callback)); - } - - public void clearProxyOverride(Runnable callback) { - ThreadUtils.runOnUiThread(() -> AwContentsStatics.clearProxyOverride(callback)); - } }
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java index 87673a1..5de4624 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java
@@ -25,6 +25,7 @@ import org.chromium.android_webview.AwContentsStatics; import org.chromium.android_webview.AwCookieManager; import org.chromium.android_webview.AwNetworkChangeNotifierRegistrationPolicy; +import org.chromium.android_webview.AwProxyController; import org.chromium.android_webview.AwQuotaManagerBridge; import org.chromium.android_webview.AwResource; import org.chromium.android_webview.AwServiceWorkerController; @@ -72,6 +73,7 @@ private AwTracingController mAwTracingController; private VariationsSeedLoader mSeedLoader; private Thread mSetUpResourcesThread; + private AwProxyController mAwProxyController; // Guards accees to the other members, and is notifyAll() signalled on the UI thread // when the chromium process has been started. @@ -99,6 +101,15 @@ return mAwTracingController; } + public AwProxyController getAwProxyController() { + synchronized (mLock) { + if (mAwProxyController == null) { + ensureChromiumStartedLocked(true); + } + } + return mAwProxyController; + } + // TODO: DIR_RESOURCE_PAKS_ANDROID needs to live somewhere sensible, // inlined here for simplicity setting up the HTMLViewer demo. Unfortunately // it can't go into base.PathService, as the native constant it refers to @@ -181,6 +192,7 @@ mWebStorage = new WebStorageAdapter(mFactory, AwQuotaManagerBridge.getInstance()); mAwTracingController = awBrowserContext.getTracingController(); mServiceWorkerController = awBrowserContext.getServiceWorkerController(); + mAwProxyController = new AwProxyController(); } mFactory.getRunQueue().drainQueue();
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java b/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java index 0c85343..9c20328 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java
@@ -121,21 +121,6 @@ nativeSetCheckClearTextPermitted(permitted); } - @CalledByNative - private static void proxyOverrideChanged(Runnable callback) { - if (callback == null) return; - callback.run(); - } - - public static void setProxyOverride( - String host, int port, String[] exclusionList, Runnable callback) { - nativeSetProxyOverride(host, port, exclusionList, callback); - } - - public static void clearProxyOverride(Runnable callback) { - nativeClearProxyOverride(callback); - } - /** * Return the first substring consisting of the address of a physical location. * @see {@link android.webkit.WebView#findAddress(String)} @@ -162,7 +147,4 @@ private static native void nativeSetSafeBrowsingWhitelist( String[] urls, Callback<Boolean> callback); private static native void nativeSetCheckClearTextPermitted(boolean permitted); - private static native void nativeSetProxyOverride( - String host, int port, String[] exclusionList, Runnable callback); - private static native void nativeClearProxyOverride(Runnable callback); }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwProxyController.java b/android_webview/java/src/org/chromium/android_webview/AwProxyController.java new file mode 100644 index 0000000..419fc7f --- /dev/null +++ b/android_webview/java/src/org/chromium/android_webview/AwProxyController.java
@@ -0,0 +1,70 @@ +// 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.android_webview; + +import org.chromium.base.annotations.CalledByNativeUnchecked; +import org.chromium.base.annotations.JNINamespace; + +import java.util.concurrent.Executor; + +/** + * Manages proxy override functionality in WebView. + */ +@JNINamespace("android_webview") +public class AwProxyController { + public AwProxyController() {} + + public void setProxyOverride( + String[][] proxyRules, String[] bypassRules, Runnable listener, Executor executor) { + int length = (proxyRules == null ? 0 : proxyRules.length); + String[] urlSchemes = new String[length]; + String[] proxyUrls = new String[length]; + for (int i = 0; i < length; i++) { + // URL schemes + if (proxyRules[i][0] == null) { + urlSchemes[i] = "*"; + } else { + urlSchemes[i] = proxyRules[i][0]; + } + // proxy URLs + proxyUrls[i] = proxyRules[i][1]; + if (proxyUrls[i] == null) { + throw new NullPointerException("Proxy rule " + i + " has a null url"); + } + } + length = (bypassRules == null ? 0 : bypassRules.length); + for (int i = 0; i < length; i++) { + if (bypassRules[i] == null) { + throw new NullPointerException("Bypass rule " + i + " is null"); + } + } + if (executor == null) { + throw new NullPointerException("Executor must not be null"); + } + + String result = + nativeSetProxyOverride(urlSchemes, proxyUrls, bypassRules, listener, executor); + if (!result.isEmpty()) { + throw new IllegalArgumentException(result); + } + } + + public void clearProxyOverride(Runnable listener, Executor executor) { + if (executor == null) { + throw new NullPointerException("Executor must not be null"); + } + nativeClearProxyOverride(listener, executor); + } + + @CalledByNativeUnchecked + private void proxyOverrideChanged(Runnable listener, Executor executor) { + if (listener == null) return; + executor.execute(listener); + } + + private native String nativeSetProxyOverride(String[] urlSchemes, String[] proxyUrls, + String[] bypassRules, Runnable listener, Executor executor); + private native void nativeClearProxyOverride(Runnable listener, Executor executor); +} \ No newline at end of file
diff --git a/android_webview/renderer/aw_content_renderer_client.cc b/android_webview/renderer/aw_content_renderer_client.cc index 02354579..7987ac7 100644 --- a/android_webview/renderer/aw_content_renderer_client.cc +++ b/android_webview/renderer/aw_content_renderer_client.cc
@@ -193,8 +193,9 @@ void AwContentRendererClient::PrepareErrorPage( content::RenderFrame* render_frame, - const blink::WebURLRequest& failed_request, const blink::WebURLError& error, + const std::string& http_method, + bool ignoring_cache, std::string* error_html) { std::string err; if (error.reason() == net::ERR_TEMPORARILY_THROTTLED) @@ -206,7 +207,7 @@ return; // Create the error page based on the error reason. - GURL gurl(failed_request.Url()); + GURL gurl(error.url()); std::string url_string = gurl.possibly_invalid_spec(); int reason_id = IDS_AW_WEBPAGE_CAN_NOT_BE_LOADED;
diff --git a/android_webview/renderer/aw_content_renderer_client.h b/android_webview/renderer/aw_content_renderer_client.h index 9c6906e..f6ae6dc 100644 --- a/android_webview/renderer/aw_content_renderer_client.h +++ b/android_webview/renderer/aw_content_renderer_client.h
@@ -38,8 +38,9 @@ void RenderViewCreated(content::RenderView* render_view) override; bool HasErrorPage(int http_status_code) override; void PrepareErrorPage(content::RenderFrame* render_frame, - const blink::WebURLRequest& failed_request, const blink::WebURLError& error, + const std::string& http_method, + bool ignoring_cache, std::string* error_html) override; unsigned long long VisitedLinkHash(const char* canonical_url, size_t length) override;
diff --git a/android_webview/support_library/BUILD.gn b/android_webview/support_library/BUILD.gn index 82deb18e..48f7933 100644 --- a/android_webview/support_library/BUILD.gn +++ b/android_webview/support_library/BUILD.gn
@@ -8,6 +8,7 @@ android_library("support_lib_glue_java") { java_files = [ "java/src/org/chromium/support_lib_glue/IsomorphicAdapter.java", + "java/src/org/chromium/support_lib_glue/SupportLibProxyControllerAdapter.java", "java/src/org/chromium/support_lib_glue/SupportLibReflectionUtil.java", "java/src/org/chromium/support_lib_glue/SupportLibServiceWorkerClientAdapter.java", "java/src/org/chromium/support_lib_glue/SupportLibServiceWorkerControllerAdapter.java",
diff --git a/android_webview/support_library/boundary_interfaces/BUILD.gn b/android_webview/support_library/boundary_interfaces/BUILD.gn index cc7e835..2111854 100644 --- a/android_webview/support_library/boundary_interfaces/BUILD.gn +++ b/android_webview/support_library/boundary_interfaces/BUILD.gn
@@ -9,6 +9,7 @@ java_files = [ "src/org/chromium/support_lib_boundary/FeatureFlagHolderBoundaryInterface.java", "src/org/chromium/support_lib_boundary/IsomorphicObjectBoundaryInterface.java", + "src/org/chromium/support_lib_boundary/ProxyControllerBoundaryInterface.java", "src/org/chromium/support_lib_boundary/SafeBrowsingResponseBoundaryInterface.java", "src/org/chromium/support_lib_boundary/ServiceWorkerClientBoundaryInterface.java", "src/org/chromium/support_lib_boundary/ServiceWorkerControllerBoundaryInterface.java",
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/ProxyControllerBoundaryInterface.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/ProxyControllerBoundaryInterface.java new file mode 100644 index 0000000..f9abc59 --- /dev/null +++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/ProxyControllerBoundaryInterface.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.support_lib_boundary; + +import java.util.concurrent.Executor; + +/** + * Boundary interface for ProxyController. + */ +public interface ProxyControllerBoundaryInterface { + void setProxyOverride( + String[][] proxyRules, String[] bypassRules, Runnable listener, Executor executor); + void clearProxyOverride(Runnable listener, Executor executor); +}
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/StaticsBoundaryInterface.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/StaticsBoundaryInterface.java index 5511b39..d60a60dd 100644 --- a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/StaticsBoundaryInterface.java +++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/StaticsBoundaryInterface.java
@@ -17,6 +17,4 @@ void initSafeBrowsing(Context context, ValueCallback<Boolean> callback); void setSafeBrowsingWhitelist(List<String> hosts, ValueCallback<Boolean> callback); Uri getSafeBrowsingPrivacyPolicyUrl(); - void setProxyOverride(String host, int port, String[] exclusionList, Runnable callback); - void clearProxyOverride(Runnable callback); }
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewProviderFactoryBoundaryInterface.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewProviderFactoryBoundaryInterface.java index b971ed6f..15db689 100644 --- a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewProviderFactoryBoundaryInterface.java +++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewProviderFactoryBoundaryInterface.java
@@ -17,4 +17,5 @@ String[] getSupportedFeatures(); /* SupportLibraryServiceWorkerController */ InvocationHandler getServiceWorkerController(); /* SupportLibraryTracingController */ InvocationHandler getTracingController(); + /* SupportLibraryProxyController */ InvocationHandler getProxyController(); }
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 287bcc0..cf5dbf1f 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
@@ -128,9 +128,9 @@ // WebViewCompat.getWebChromeClient public static final String GET_WEB_CHROME_CLIENT = "GET_WEB_CHROME_CLIENT"; - // WebViewCompat.setProxyOverride - // WebViewCompat.clearProxyOverride - public static final String PROXY_OVERRIDE = "PROXY_OVERRIDE:2"; + // ProxyController.setProxyOverride + // ProxyController.clearProxyOverride + public static final String PROXY_OVERRIDE = "PROXY_OVERRIDE:3" + DEV_SUFFIX; // WebViewCompat.getWebViewRenderer public static final String GET_WEB_VIEW_RENDERER = "GET_WEB_VIEW_RENDERER";
diff --git a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibProxyControllerAdapter.java b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibProxyControllerAdapter.java new file mode 100644 index 0000000..1c3b24b --- /dev/null +++ b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibProxyControllerAdapter.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.support_lib_glue; + +import org.chromium.android_webview.AwProxyController; +import org.chromium.support_lib_boundary.ProxyControllerBoundaryInterface; + +import java.util.concurrent.Executor; + +/** + * Adapter between AwProxyController and ProxyControllerBoundaryInterface. + */ +public class SupportLibProxyControllerAdapter implements ProxyControllerBoundaryInterface { + private final AwProxyController mProxyController; + + public SupportLibProxyControllerAdapter(AwProxyController proxyController) { + mProxyController = proxyController; + } + + @Override + public void setProxyOverride( + String[][] proxyRules, String[] bypassRules, Runnable listener, Executor executor) { + mProxyController.setProxyOverride(proxyRules, bypassRules, listener, executor); + } + + @Override + public void clearProxyOverride(Runnable listener, Executor executor) { + mProxyController.clearProxyOverride(listener, executor); + } +} \ No newline at end of file
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 a6dcb74b..7db638e0 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
@@ -76,6 +76,7 @@ private InvocationHandler mStatics; private InvocationHandler mServiceWorkerController; private InvocationHandler mTracingController; + private InvocationHandler mProxyController; public SupportLibWebViewChromiumFactory() { mCompatConverterAdapter = BoundaryInterfaceReflectionUtil.createInvocationHandlerFor( @@ -117,17 +118,6 @@ public Uri getSafeBrowsingPrivacyPolicyUrl() { return mSharedStatics.getSafeBrowsingPrivacyPolicyUrl(); } - - @Override - public void setProxyOverride( - String host, int port, String[] exclusionList, Runnable callback) { - mSharedStatics.setProxyOverride(host, port, exclusionList, callback); - } - - @Override - public void clearProxyOverride(Runnable callback) { - mSharedStatics.clearProxyOverride(callback); - } } @Override @@ -171,4 +161,15 @@ } return mTracingController; } + + @Override + public InvocationHandler getProxyController() { + synchronized (mAwInit.getLock()) { + if (mProxyController == null) { + mProxyController = BoundaryInterfaceReflectionUtil.createInvocationHandlerFor( + new SupportLibProxyControllerAdapter(mAwInit.getAwProxyController())); + } + } + return mProxyController; + } }
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index e235cee..d4c892d 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -510,6 +510,8 @@ "media/media_notification_constants.h", "media/media_notification_controller.cc", "media/media_notification_controller.h", + "media/media_notification_item.cc", + "media/media_notification_item.h", "media/media_notification_view.cc", "media/media_notification_view.h", "media_controller.cc",
diff --git a/ash/assistant/assistant_controller.cc b/ash/assistant/assistant_controller.cc index 46ef257..9b4a567 100644 --- a/ash/assistant/assistant_controller.cc +++ b/ash/assistant/assistant_controller.cc
@@ -100,6 +100,11 @@ OpenUrl(assistant::util::CreateAssistantSettingsDeepLink()); } +void AssistantController::StartSpeakerIdEnrollmentFlow() { + setup_controller()->StartOnboarding(false /* relaunch */, + mojom::FlowType::SPEAKER_ID_ENROLLMENT); +} + void AssistantController::DownloadImage( const GURL& url, mojom::AssistantImageDownloader::DownloadCallback callback) {
diff --git a/ash/assistant/assistant_controller.h b/ash/assistant/assistant_controller.h index 51497795..6fbae32 100644 --- a/ash/assistant/assistant_controller.h +++ b/ash/assistant/assistant_controller.h
@@ -81,6 +81,7 @@ void SetAssistantImageDownloader( mojom::AssistantImageDownloaderPtr assistant_image_downloader) override; void OpenAssistantSettings() override; + void StartSpeakerIdEnrollmentFlow() override; // AssistantControllerObserver: void OnDeepLinkReceived(
diff --git a/ash/assistant/assistant_setup_controller.cc b/ash/assistant/assistant_setup_controller.cc index 61970fd6..f252016 100644 --- a/ash/assistant/assistant_setup_controller.cc +++ b/ash/assistant/assistant_setup_controller.cc
@@ -48,22 +48,26 @@ StartOnboarding(/*relaunch=*/true); } -void AssistantSetupController::StartOnboarding(bool relaunch) { +void AssistantSetupController::StartOnboarding(bool relaunch, + mojom::FlowType type) { if (!assistant_setup_) return; if (relaunch) { - assistant_setup_->StartAssistantOptInFlow(base::BindOnce( - [](AssistantController* assistant_controller, bool completed) { - if (completed) { - assistant_controller->ui_controller()->ShowUi( - AssistantEntryPoint::kSetup); - } - }, - // AssistantController owns |assistant_setup_| so a raw pointer is safe. - assistant_controller_)); + assistant_setup_->StartAssistantOptInFlow( + type, + base::BindOnce( + [](AssistantController* assistant_controller, bool completed) { + if (completed) { + assistant_controller->ui_controller()->ShowUi( + AssistantEntryPoint::kSetup); + } + }, + // AssistantController owns |assistant_setup_| so a raw pointer is + // safe. + assistant_controller_)); } else { - assistant_setup_->StartAssistantOptInFlow(base::DoNothing()); + assistant_setup_->StartAssistantOptInFlow(type, base::DoNothing()); } // Assistant UI should be hidden while the user onboards.
diff --git a/ash/assistant/assistant_setup_controller.h b/ash/assistant/assistant_setup_controller.h index b5171229..986c261 100644 --- a/ash/assistant/assistant_setup_controller.h +++ b/ash/assistant/assistant_setup_controller.h
@@ -39,9 +39,10 @@ // AssistantOptInDelegate: void OnOptInButtonPressed() override; - private: - void StartOnboarding(bool relaunch); + void StartOnboarding(bool relaunch, + mojom::FlowType type = mojom::FlowType::CONSENT_FLOW); + private: AssistantController* const assistant_controller_; // Owned by Shell. mojo::Binding<mojom::AssistantSetupController> binding_;
diff --git a/ash/media/media_notification_constants.cc b/ash/media/media_notification_constants.cc index 4aeed88..a28c11c2 100644 --- a/ash/media/media_notification_constants.cc +++ b/ash/media/media_notification_constants.cc
@@ -6,8 +6,6 @@ namespace ash { -const char kMediaSessionNotificationId[] = "media-session"; - const char kMediaSessionNotificationCustomViewType[] = "media-session"; const char kMediaSessionNotifierId[] = "media-session";
diff --git a/ash/media/media_notification_constants.h b/ash/media/media_notification_constants.h index f72a0ec7..dbc4753 100644 --- a/ash/media/media_notification_constants.h +++ b/ash/media/media_notification_constants.h
@@ -9,9 +9,6 @@ namespace ash { -// The notification ID for the media session notification. -ASH_EXPORT extern const char kMediaSessionNotificationId[]; - // The custom view type that should be set on media session notifications. ASH_EXPORT extern const char kMediaSessionNotificationCustomViewType[];
diff --git a/ash/media/media_notification_controller.cc b/ash/media/media_notification_controller.cc index 7d90410..3b4da98e 100644 --- a/ash/media/media_notification_controller.cc +++ b/ash/media/media_notification_controller.cc
@@ -6,29 +6,15 @@ #include "ash/media/media_notification_constants.h" #include "ash/media/media_notification_view.h" -#include "ash/public/cpp/notification_utils.h" -#include "base/strings/string16.h" -#include "base/time/time.h" +#include "base/stl_util.h" #include "services/media_session/public/mojom/constants.mojom.h" -#include "services/media_session/public/mojom/media_controller.mojom.h" -#include "services/media_session/public/mojom/media_session.mojom.h" #include "services/service_manager/public/cpp/connector.h" -#include "ui/gfx/image/image.h" -#include "ui/message_center/public/cpp/notification.h" -#include "ui/message_center/public/cpp/notification_delegate.h" -#include "ui/message_center/public/cpp/notifier_id.h" #include "ui/message_center/views/message_view_factory.h" -#include "url/gurl.h" namespace ash { -using media_session::mojom::MediaSessionAction; - namespace { -constexpr base::TimeDelta kDefaultSeekTime = - base::TimeDelta::FromSeconds(media_session::mojom::kDefaultSeekTimeSeconds); - std::unique_ptr<message_center::MessageView> CreateCustomMediaNotificationView( const message_center::Notification& notification) { DCHECK_EQ(kMediaSessionNotificationCustomViewType, @@ -36,11 +22,6 @@ return std::make_unique<MediaNotificationView>(notification); } -bool IsMediaSessionNotificationVisible() { - return message_center::MessageCenter::Get()->FindVisibleNotificationById( - kMediaSessionNotificationId) != nullptr; -} - } // namespace MediaNotificationController::MediaNotificationController( @@ -59,120 +40,51 @@ media_session::mojom::AudioFocusManagerPtr audio_focus_ptr; connector->BindInterface(media_session::mojom::kServiceName, mojo::MakeRequest(&audio_focus_ptr)); + + media_session::mojom::MediaControllerManagerPtr controller_manager_ptr; connector->BindInterface(media_session::mojom::kServiceName, - mojo::MakeRequest(&media_controller_ptr_)); + mojo::MakeRequest(&controller_manager_ptr)); media_session::mojom::AudioFocusObserverPtr audio_focus_observer; audio_focus_observer_binding_.Bind(mojo::MakeRequest(&audio_focus_observer)); audio_focus_ptr->AddObserver(std::move(audio_focus_observer)); - - media_session::mojom::MediaSessionObserverPtr media_session_observer; - media_session_observer_binding_.Bind( - mojo::MakeRequest(&media_session_observer)); - media_controller_ptr_->AddObserver(std::move(media_session_observer)); } MediaNotificationController::~MediaNotificationController() = default; -void MediaNotificationController::OnActiveSessionChanged( +void MediaNotificationController::OnFocusGained( media_session::mojom::AudioFocusRequestStatePtr session) { - // Hide the notification if the active session is null. - if (session.is_null()) { - message_center::MessageCenter::Get()->RemoveNotification( - kMediaSessionNotificationId, false); - return; - } + const std::string id = session->request_id->ToString(); - if (IsMediaSessionNotificationVisible()) + if (base::ContainsKey(notifications_, id)) return; - session_info_ = std::move(session->session_info); + media_session::mojom::MediaControllerPtr controller; - std::unique_ptr<message_center::Notification> notification = - ash::CreateSystemNotification( - message_center::NotificationType::NOTIFICATION_TYPE_CUSTOM, - kMediaSessionNotificationId, base::string16(), base::string16(), - base::string16(), GURL(), - message_center::NotifierId( - message_center::NotifierType::SYSTEM_COMPONENT, - kMediaSessionNotifierId), - message_center::RichNotificationData(), - base::MakeRefCounted<message_center::HandleNotificationClickDelegate>( - base::BindRepeating( - &MediaNotificationController::OnNotificationClicked, - weak_ptr_factory_.GetWeakPtr())), - gfx::VectorIcon(), - message_center::SystemNotificationWarningLevel::NORMAL); - - // Set the priority to low to prevent the notification showing as a popup and - // keep it at the bottom of the list. - notification->set_priority(message_center::LOW_PRIORITY); - - notification->set_custom_view_type(kMediaSessionNotificationCustomViewType); - - message_center::MessageCenter::Get()->AddNotification( - std::move(notification)); -} - -void MediaNotificationController::MediaSessionInfoChanged( - media_session::mojom::MediaSessionInfoPtr session_info) { - session_info_ = std::move(session_info); - - if (view_) - view_->UpdateWithMediaSessionInfo(session_info_); -} - -void MediaNotificationController::MediaSessionMetadataChanged( - const base::Optional<media_session::MediaMetadata>& metadata) { - session_metadata_ = metadata.value_or(media_session::MediaMetadata()); - - if (view_) - view_->UpdateWithMediaMetadata(session_metadata_); -} - -void MediaNotificationController::FlushForTesting() { - media_controller_ptr_.FlushForTesting(); -} - -void MediaNotificationController::SetView(MediaNotificationView* view) { - DCHECK(view_ || view); - - view_ = view; - - if (view) { - DCHECK(!session_info_.is_null()); - view_->UpdateWithMediaSessionInfo(session_info_); - view_->UpdateWithMediaMetadata(session_metadata_); + // |controller_manager_ptr_| may be null in tests where connector is + // unavailable. + if (controller_manager_ptr_) { + controller_manager_ptr_->CreateMediaControllerForSession( + mojo::MakeRequest(&controller), *session->request_id); } + + notifications_.emplace( + std::piecewise_construct, std::forward_as_tuple(id), + std::forward_as_tuple(id, std::move(controller), + std::move(session->session_info))); } -void MediaNotificationController::OnNotificationClicked( - base::Optional<int> button_id) { - DCHECK(button_id.has_value()); +void MediaNotificationController::OnFocusLost( + media_session::mojom::AudioFocusRequestStatePtr session) { + notifications_.erase(session->request_id->ToString()); +} - switch (static_cast<MediaSessionAction>(*button_id)) { - case MediaSessionAction::kPreviousTrack: - media_controller_ptr_->PreviousTrack(); - break; - case MediaSessionAction::kSeekBackward: - media_controller_ptr_->Seek(kDefaultSeekTime * -1); - break; - case MediaSessionAction::kPlay: - media_controller_ptr_->Resume(); - break; - case MediaSessionAction::kPause: - media_controller_ptr_->Suspend(); - break; - case MediaSessionAction::kSeekForward: - media_controller_ptr_->Seek(kDefaultSeekTime); - break; - case MediaSessionAction::kNextTrack: - media_controller_ptr_->NextTrack(); - break; - case MediaSessionAction::kStop: - media_controller_ptr_->Stop(); - break; - } +void MediaNotificationController::SetView(const std::string& id, + MediaNotificationView* view) { + auto it = notifications_.find(id); + if (it == notifications_.end()) + return; + it->second.SetView(view); } } // namespace ash
diff --git a/ash/media/media_notification_controller.h b/ash/media/media_notification_controller.h index b574dca..27d4f28 100644 --- a/ash/media/media_notification_controller.h +++ b/ash/media/media_notification_controller.h
@@ -5,13 +5,16 @@ #ifndef ASH_MEDIA_MEDIA_NOTIFICATION_CONTROLLER_H_ #define ASH_MEDIA_MEDIA_NOTIFICATION_CONTROLLER_H_ +#include <map> +#include <memory> +#include <string> + #include "ash/ash_export.h" +#include "ash/media/media_notification_item.h" #include "base/macros.h" -#include "base/memory/weak_ptr.h" #include "mojo/public/cpp/bindings/binding.h" #include "services/media_session/public/mojom/audio_focus.mojom.h" #include "services/media_session/public/mojom/media_controller.mojom.h" -#include "ui/message_center/message_center.h" namespace service_manager { class Connector; @@ -19,59 +22,43 @@ namespace ash { +class MediaNotificationItem; class MediaNotificationView; -// MediaNotificationController will show/hide a media notification when a media -// session is active. This notification will show metadata and playback +// MediaNotificationController will show/hide media notifications when media +// sessions are active. These notifications will show metadata and playback // controls. class ASH_EXPORT MediaNotificationController - : public media_session::mojom::AudioFocusObserver, - public media_session::mojom::MediaSessionObserver { + : public media_session::mojom::AudioFocusObserver { public: explicit MediaNotificationController(service_manager::Connector* connector); ~MediaNotificationController() override; // media_session::mojom::AudioFocusObserver: void OnFocusGained( - media_session::mojom::AudioFocusRequestStatePtr session) override {} - void OnFocusLost( - media_session::mojom::AudioFocusRequestStatePtr session) override {} - void OnActiveSessionChanged( media_session::mojom::AudioFocusRequestStatePtr session) override; + void OnFocusLost( + media_session::mojom::AudioFocusRequestStatePtr session) override; + void OnActiveSessionChanged( + media_session::mojom::AudioFocusRequestStatePtr session) override {} - // media_session::mojom::MediaSessionObserver: - void MediaSessionInfoChanged( - media_session::mojom::MediaSessionInfoPtr session_info) override; - void MediaSessionMetadataChanged( - const base::Optional<media_session::MediaMetadata>& metadata) override; + void SetView(const std::string& id, MediaNotificationView* view); - void FlushForTesting(); - void SetMediaControllerForTesting( - media_session::mojom::MediaControllerPtr controller) { - media_controller_ptr_ = std::move(controller); + MediaNotificationItem* GetItem(const std::string& id) { + auto it = notifications_.find(id); + DCHECK(it != notifications_.end()); + return &it->second; } - void SetView(MediaNotificationView* view); - private: - // Weak reference to the view of the currently shown media notification. - MediaNotificationView* view_ = nullptr; - - void OnNotificationClicked(base::Optional<int> button_id); - - media_session::mojom::MediaControllerPtr media_controller_ptr_; - - media_session::mojom::MediaSessionInfoPtr session_info_; - - media_session::MediaMetadata session_metadata_; + media_session::mojom::MediaControllerManagerPtr controller_manager_ptr_; mojo::Binding<media_session::mojom::AudioFocusObserver> audio_focus_observer_binding_{this}; - mojo::Binding<media_session::mojom::MediaSessionObserver> - media_session_observer_binding_{this}; - - base::WeakPtrFactory<MediaNotificationController> weak_ptr_factory_{this}; + // Stores a |MediaNotificationItem| for each media session keyed by its + // |request_id| in string format. + std::map<const std::string, MediaNotificationItem> notifications_; DISALLOW_COPY_AND_ASSIGN(MediaNotificationController); };
diff --git a/ash/media/media_notification_controller_unittest.cc b/ash/media/media_notification_controller_unittest.cc index 3fc8739..4d2d475 100644 --- a/ash/media/media_notification_controller_unittest.cc +++ b/ash/media/media_notification_controller_unittest.cc
@@ -7,31 +7,35 @@ #include <memory> #include "ash/media/media_notification_constants.h" +#include "ash/media/media_notification_item.h" #include "ash/public/cpp/ash_features.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "base/macros.h" #include "base/test/scoped_feature_list.h" +#include "base/unguessable_token.h" #include "services/media_session/public/mojom/audio_focus.mojom.h" #include "ui/message_center/message_center.h" namespace ash { -using media_session::mojom::AudioFocusRequestState; - namespace { -bool IsMediaNotificationShown() { - return message_center::MessageCenter::Get()->FindVisibleNotificationById( - kMediaSessionNotificationId); +media_session::mojom::MediaSessionInfoPtr BuildMediaSessionInfo( + bool is_controllable) { + media_session::mojom::MediaSessionInfoPtr session_info( + media_session::mojom::MediaSessionInfo::New()); + session_info->is_controllable = is_controllable; + return session_info; } -int GetVisibleNotificationCount() { - return message_center::MessageCenter::Get()->GetVisibleNotifications().size(); -} - -int GetPopupNotificationCount() { - return message_center::MessageCenter::Get()->GetPopupNotifications().size(); +media_session::mojom::AudioFocusRequestStatePtr GetRequestStateWithId( + const base::UnguessableToken& id) { + media_session::mojom::AudioFocusRequestStatePtr session( + media_session::mojom::AudioFocusRequestState::New()); + session->request_id = id; + session->session_info = BuildMediaSessionInfo(true); + return session; } } // namespace @@ -49,52 +53,138 @@ AshTestBase::SetUp(); } + void ExpectNotificationCount(unsigned count) { + message_center::MessageCenter* message_center = + message_center::MessageCenter::Get(); + + EXPECT_EQ(count, message_center->GetVisibleNotifications().size()); + + // Media notifications should never be shown as a popup so we always check + // this is empty. + EXPECT_TRUE(message_center->GetPopupNotifications().empty()); + } + private: base::test::ScopedFeatureList scoped_feature_list_; DISALLOW_COPY_AND_ASSIGN(MediaNotificationControllerTest); }; -TEST_F(MediaNotificationControllerTest, OnActiveSessionChanged) { - EXPECT_FALSE(IsMediaNotificationShown()); - EXPECT_EQ(0, GetVisibleNotificationCount()); - EXPECT_EQ(0, GetPopupNotificationCount()); +// Test toggling the notification multiple times with the same ID. Since the +// notification is keyed by ID we should only ever show one. +TEST_F(MediaNotificationControllerTest, OnFocusGainedLost_SameId) { + base::UnguessableToken id = base::UnguessableToken::Create(); - Shell::Get()->media_notification_controller()->OnActiveSessionChanged( - AudioFocusRequestState::New()); - EXPECT_TRUE(IsMediaNotificationShown()); - EXPECT_EQ(1, GetVisibleNotificationCount()); - EXPECT_EQ(0, GetPopupNotificationCount()); + ExpectNotificationCount(0); - Shell::Get()->media_notification_controller()->OnActiveSessionChanged( - AudioFocusRequestState::New()); - EXPECT_TRUE(IsMediaNotificationShown()); - EXPECT_EQ(1, GetVisibleNotificationCount()); - EXPECT_EQ(0, GetPopupNotificationCount()); + Shell::Get()->media_notification_controller()->OnFocusGained( + GetRequestStateWithId(id)); - Shell::Get()->media_notification_controller()->OnActiveSessionChanged( - nullptr); - EXPECT_FALSE(IsMediaNotificationShown()); - EXPECT_EQ(0, GetVisibleNotificationCount()); - EXPECT_EQ(0, GetPopupNotificationCount()); + ExpectNotificationCount(1); + + Shell::Get()->media_notification_controller()->OnFocusGained( + GetRequestStateWithId(id)); + + ExpectNotificationCount(1); + + Shell::Get()->media_notification_controller()->OnFocusLost( + GetRequestStateWithId(id)); + + ExpectNotificationCount(0); } -TEST_F(MediaNotificationControllerTest, OnActiveSessionChanged_Noop) { - EXPECT_FALSE(IsMediaNotificationShown()); +// Test toggling the notification multiple times with different IDs. This should +// show one notification per ID. +TEST_F(MediaNotificationControllerTest, OnFocusGainedLost_MultipleIds) { + base::UnguessableToken id1 = base::UnguessableToken::Create(); + base::UnguessableToken id2 = base::UnguessableToken::Create(); - Shell::Get()->media_notification_controller()->OnActiveSessionChanged( - nullptr); - EXPECT_FALSE(IsMediaNotificationShown()); + ExpectNotificationCount(0); + + Shell::Get()->media_notification_controller()->OnFocusGained( + GetRequestStateWithId(id1)); + + ExpectNotificationCount(1); + + Shell::Get()->media_notification_controller()->OnFocusGained( + GetRequestStateWithId(id2)); + + ExpectNotificationCount(2); + + Shell::Get()->media_notification_controller()->OnFocusLost( + GetRequestStateWithId(id1)); + + ExpectNotificationCount(1); } +// Test that a notification is hidden when it becomes uncontrollable. We still +// keep the MediaNotificationItem around in case it becomes controllable again. +TEST_F(MediaNotificationControllerTest, + OnFocusGained_ControllableBecomesUncontrollable) { + base::UnguessableToken id = base::UnguessableToken::Create(); + + ExpectNotificationCount(0); + + Shell::Get()->media_notification_controller()->OnFocusGained( + GetRequestStateWithId(id)); + + ExpectNotificationCount(1); + + Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->MediaSessionInfoChanged(BuildMediaSessionInfo(false)); + + ExpectNotificationCount(0); +} + +// Test that a notification is shown when it becomes controllable. +TEST_F(MediaNotificationControllerTest, + OnFocusGained_NotControllableBecomesControllable) { + base::UnguessableToken id = base::UnguessableToken::Create(); + + ExpectNotificationCount(0); + + media_session::mojom::AudioFocusRequestStatePtr state = + GetRequestStateWithId(id); + state->session_info->is_controllable = false; + Shell::Get()->media_notification_controller()->OnFocusGained( + std::move(state)); + + ExpectNotificationCount(0); + + Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->MediaSessionInfoChanged(BuildMediaSessionInfo(true)); + + ExpectNotificationCount(1); +} + +// Test hiding a notification with an invalid ID. +TEST_F(MediaNotificationControllerTest, OnFocusLost_Noop) { + ExpectNotificationCount(0); + + Shell::Get()->media_notification_controller()->OnFocusLost( + GetRequestStateWithId(base::UnguessableToken::Create())); + + ExpectNotificationCount(0); +} + +// Test that media notifications have the correct custom view type. TEST_F(MediaNotificationControllerTest, NotificationHasCustomViewType) { - EXPECT_FALSE(IsMediaNotificationShown()); + ExpectNotificationCount(0); - Shell::Get()->media_notification_controller()->OnActiveSessionChanged( - AudioFocusRequestState::New()); + base::UnguessableToken id = base::UnguessableToken::Create(); + + Shell::Get()->media_notification_controller()->OnFocusGained( + GetRequestStateWithId(id)); + + ExpectNotificationCount(1); + message_center::Notification* notification = message_center::MessageCenter::Get()->FindVisibleNotificationById( - kMediaSessionNotificationId); + id.ToString()); EXPECT_TRUE(notification); EXPECT_EQ(kMediaSessionNotificationCustomViewType,
diff --git a/ash/media/media_notification_item.cc b/ash/media/media_notification_item.cc new file mode 100644 index 0000000..ac44a05 --- /dev/null +++ b/ash/media/media_notification_item.cc
@@ -0,0 +1,154 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/media/media_notification_item.h" + +#include "ash/media/media_notification_constants.h" +#include "ash/media/media_notification_view.h" +#include "ash/public/cpp/notification_utils.h" +#include "base/strings/string16.h" +#include "base/time/time.h" +#include "services/media_session/public/mojom/constants.mojom.h" +#include "services/media_session/public/mojom/media_controller.mojom.h" +#include "services/media_session/public/mojom/media_session.mojom.h" +#include "ui/gfx/image/image.h" +#include "ui/message_center/message_center.h" +#include "ui/message_center/public/cpp/notification.h" +#include "ui/message_center/public/cpp/notification_delegate.h" +#include "ui/message_center/public/cpp/notifier_id.h" +#include "url/gurl.h" + +namespace ash { + +using media_session::mojom::MediaSessionAction; + +namespace { + +constexpr base::TimeDelta kDefaultSeekTime = + base::TimeDelta::FromSeconds(media_session::mojom::kDefaultSeekTimeSeconds); + +} // namespace + +MediaNotificationItem::MediaNotificationItem( + const std::string& id, + media_session::mojom::MediaControllerPtr controller, + media_session::mojom::MediaSessionInfoPtr session_info) + : id_(id), + media_controller_ptr_(std::move(controller)), + session_info_(std::move(session_info)) { + // Bind an observer to the associated media session. + if (media_controller_ptr_.is_bound()) { + media_session::mojom::MediaSessionObserverPtr media_session_observer; + observer_binding_.Bind(mojo::MakeRequest(&media_session_observer)); + media_controller_ptr_->AddObserver(std::move(media_session_observer)); + } + + MaybeHideOrShowNotification(); +} + +MediaNotificationItem::~MediaNotificationItem() { + HideNotification(); +} + +void MediaNotificationItem::MediaSessionInfoChanged( + media_session::mojom::MediaSessionInfoPtr session_info) { + session_info_ = std::move(session_info); + + MaybeHideOrShowNotification(); + + if (view_) + view_->UpdateWithMediaSessionInfo(session_info_); +} + +void MediaNotificationItem::MediaSessionMetadataChanged( + const base::Optional<media_session::MediaMetadata>& metadata) { + session_metadata_ = metadata.value_or(media_session::MediaMetadata()); + + if (view_) + view_->UpdateWithMediaMetadata(session_metadata_); +} + +void MediaNotificationItem::SetView(MediaNotificationView* view) { + DCHECK(view_ || view); + + view_ = view; + + if (view) { + DCHECK(!session_info_.is_null()); + view_->UpdateWithMediaSessionInfo(session_info_); + view_->UpdateWithMediaMetadata(session_metadata_); + } +} + +void MediaNotificationItem::FlushForTesting() { + media_controller_ptr_.FlushForTesting(); +} + +void MediaNotificationItem::MaybeHideOrShowNotification() { + // If the |is_controllable| bit is set in MediaSessionInfo then we should show + // a media notification. + if (!session_info_->is_controllable) { + HideNotification(); + return; + } + + if (message_center::MessageCenter::Get()->FindVisibleNotificationById(id_)) + return; + + std::unique_ptr<message_center::Notification> notification = + ash::CreateSystemNotification( + message_center::NotificationType::NOTIFICATION_TYPE_CUSTOM, id_, + base::string16(), base::string16(), base::string16(), GURL(), + message_center::NotifierId( + message_center::NotifierType::SYSTEM_COMPONENT, + kMediaSessionNotifierId), + message_center::RichNotificationData(), + base::MakeRefCounted<message_center::HandleNotificationClickDelegate>( + base::BindRepeating(&MediaNotificationItem::OnNotificationClicked, + weak_ptr_factory_.GetWeakPtr())), + gfx::VectorIcon(), + message_center::SystemNotificationWarningLevel::NORMAL); + + // Set the priority to low to prevent the notification showing as a popup and + // keep it at the bottom of the list. + notification->set_priority(message_center::LOW_PRIORITY); + + notification->set_custom_view_type(kMediaSessionNotificationCustomViewType); + + message_center::MessageCenter::Get()->AddNotification( + std::move(notification)); +} + +void MediaNotificationItem::HideNotification() { + message_center::MessageCenter::Get()->RemoveNotification(id_, false); +} + +void MediaNotificationItem::OnNotificationClicked( + base::Optional<int> button_id) { + switch (static_cast<MediaSessionAction>(*button_id)) { + case MediaSessionAction::kPreviousTrack: + media_controller_ptr_->PreviousTrack(); + break; + case MediaSessionAction::kSeekBackward: + media_controller_ptr_->Seek(kDefaultSeekTime * -1); + break; + case MediaSessionAction::kPlay: + media_controller_ptr_->Resume(); + break; + case MediaSessionAction::kPause: + media_controller_ptr_->Suspend(); + break; + case MediaSessionAction::kSeekForward: + media_controller_ptr_->Seek(kDefaultSeekTime); + break; + case MediaSessionAction::kNextTrack: + media_controller_ptr_->NextTrack(); + break; + case MediaSessionAction::kStop: + media_controller_ptr_->Stop(); + break; + } +} + +} // namespace ash
diff --git a/ash/media/media_notification_item.h b/ash/media/media_notification_item.h new file mode 100644 index 0000000..ba06190 --- /dev/null +++ b/ash/media/media_notification_item.h
@@ -0,0 +1,79 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_MEDIA_MEDIA_NOTIFICATION_ITEM_H_ +#define ASH_MEDIA_MEDIA_NOTIFICATION_ITEM_H_ + +#include <string> + +#include "ash/ash_export.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "services/media_session/public/mojom/media_controller.mojom.h" + +namespace ash { + +class MediaNotificationView; + +// MediaNotificationItem manages hiding/showing a media notification and +// updating the metadata for a single media session. +class ASH_EXPORT MediaNotificationItem + : public media_session::mojom::MediaSessionObserver { + public: + MediaNotificationItem(const std::string& id, + media_session::mojom::MediaControllerPtr controller, + media_session::mojom::MediaSessionInfoPtr session_info); + ~MediaNotificationItem() override; + + // media_session::mojom::MediaSessionObserver: + void MediaSessionInfoChanged( + media_session::mojom::MediaSessionInfoPtr session_info) override; + void MediaSessionMetadataChanged( + const base::Optional<media_session::MediaMetadata>& metadata) override; + void MediaSessionActionsChanged( + const std::vector<media_session::mojom::MediaSessionAction>& actions) + override {} + + void SetView(MediaNotificationView* view); + + void FlushForTesting(); + + void SetMediaControllerForTesting( + media_session::mojom::MediaControllerPtr controller) { + media_controller_ptr_ = std::move(controller); + } + + private: + void MaybeHideOrShowNotification(); + + void HideNotification(); + + // Weak reference to the view of the currently shown media notification. + MediaNotificationView* view_ = nullptr; + + void OnNotificationClicked(base::Optional<int> button_id); + + // The id is the |request_id| of the media session and is guaranteed to be + // globally unique. It is also used as the id of the notification for this + // media session. + const std::string id_; + + media_session::mojom::MediaControllerPtr media_controller_ptr_; + + media_session::mojom::MediaSessionInfoPtr session_info_; + + media_session::MediaMetadata session_metadata_; + + mojo::Binding<media_session::mojom::MediaSessionObserver> observer_binding_{ + this}; + + base::WeakPtrFactory<MediaNotificationItem> weak_ptr_factory_{this}; + + DISALLOW_COPY_AND_ASSIGN(MediaNotificationItem); +}; + +} // namespace ash + +#endif // ASH_MEDIA_MEDIA_NOTIFICATION_ITEM_H_
diff --git a/ash/media/media_notification_view.cc b/ash/media/media_notification_view.cc index 6a47b6c..236985a 100644 --- a/ash/media/media_notification_view.cc +++ b/ash/media/media_notification_view.cc
@@ -140,11 +140,13 @@ message_center::kNotificationCornerRadius); UpdateViewForExpandedState(); - Shell::Get()->media_notification_controller()->SetView(this); + Shell::Get()->media_notification_controller()->SetView(notification_id(), + this); } MediaNotificationView::~MediaNotificationView() { - Shell::Get()->media_notification_controller()->SetView(nullptr); + Shell::Get()->media_notification_controller()->SetView(notification_id(), + nullptr); } void MediaNotificationView::UpdateWithNotification(
diff --git a/ash/media/media_notification_view_unittest.cc b/ash/media/media_notification_view_unittest.cc index e60796e..298d38b 100644 --- a/ash/media/media_notification_view_unittest.cc +++ b/ash/media/media_notification_view_unittest.cc
@@ -8,6 +8,7 @@ #include "ash/media/media_notification_constants.h" #include "ash/media/media_notification_controller.h" +#include "ash/media/media_notification_item.h" #include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/shell.h" @@ -18,6 +19,7 @@ #include "base/macros.h" #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" +#include "base/unguessable_token.h" #include "services/media_session/public/cpp/test/test_media_controller.h" #include "services/media_session/public/mojom/audio_focus.mojom.h" #include "services/media_session/public/mojom/media_session.mojom.h" @@ -59,9 +61,7 @@ AshTestBase::SetUp(); - media_controller_ = std::make_unique<TestMediaController>(); - Shell::Get()->media_notification_controller()->SetMediaControllerForTesting( - media_controller_->CreateMediaControllerPtr()); + request_id_ = base::UnguessableToken::Create(); ShowNotificationAndCaptureView( media_session::mojom::MediaSessionInfo::New()); @@ -85,12 +85,14 @@ media_session::mojom::AudioFocusRequestStatePtr session( media_session::mojom::AudioFocusRequestState::New()); session->session_info = std::move(session_info); - Shell::Get()->media_notification_controller()->OnActiveSessionChanged( + session->session_info->is_controllable = true; + session->request_id = request_id_; + Shell::Get()->media_notification_controller()->OnFocusGained( std::move(session)); message_center::Notification* notification = message_center::MessageCenter::Get()->FindVisibleNotificationById( - kMediaSessionNotificationId); + request_id_.ToString()); ASSERT_TRUE(notification); // Open the system tray. This will trigger the view to be created. @@ -104,6 +106,12 @@ // Check that the view was captured. ASSERT_TRUE(view_); view_->set_notify_enter_exit_on_child(true); + + // Inject the test media controller into the item. + ASSERT_TRUE(GetItem()); + media_controller_ = std::make_unique<TestMediaController>(); + GetItem()->SetMediaControllerForTesting( + media_controller_->CreateMediaControllerPtr()); } void TearDown() override { @@ -129,8 +137,7 @@ metadata.title = base::ASCIIToUTF16("title"); metadata.artist = base::ASCIIToUTF16("artist"); - Shell::Get()->media_notification_controller()->MediaSessionMetadataChanged( - metadata); + GetItem()->MediaSessionMetadataChanged(metadata); EXPECT_TRUE(title_artist_row()->visible()); EXPECT_TRUE(title_label()->visible()); @@ -166,8 +173,15 @@ return nullptr; } + MediaNotificationItem* GetItem() const { + return Shell::Get()->media_notification_controller()->GetItem( + request_id_.ToString()); + } + bool is_expanded() const { return view_->expanded_; } + const base::UnguessableToken& request_id() const { return request_id_; } + private: std::unique_ptr<message_center::MessageView> CreateAndCaptureCustomView( const message_center::Notification& notification) { @@ -176,6 +190,8 @@ return view; } + base::UnguessableToken request_id_; + base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<TestMediaController> media_controller_; @@ -242,7 +258,7 @@ GetButtonForAction(MediaSessionAction::kNextTrack), &cursor_location); GetEventGenerator()->MoveMouseTo(cursor_location); GetEventGenerator()->ClickLeftButton(); - Shell::Get()->media_notification_controller()->FlushForTesting(); + GetItem()->FlushForTesting(); EXPECT_EQ(1, media_controller()->next_track_count()); } @@ -255,7 +271,7 @@ GetButtonForAction(MediaSessionAction::kPlay), &cursor_location); GetEventGenerator()->MoveMouseTo(cursor_location); GetEventGenerator()->ClickLeftButton(); - Shell::Get()->media_notification_controller()->FlushForTesting(); + GetItem()->FlushForTesting(); EXPECT_EQ(1, media_controller()->resume_count()); } @@ -267,15 +283,15 @@ media_session::mojom::MediaSessionInfo::New()); session_info->playback_state = media_session::mojom::MediaPlaybackState::kPlaying; - Shell::Get()->media_notification_controller()->MediaSessionInfoChanged( - session_info.Clone()); + session_info->is_controllable = true; + GetItem()->MediaSessionInfoChanged(session_info.Clone()); gfx::Point cursor_location(1, 1); views::View::ConvertPointToScreen( GetButtonForAction(MediaSessionAction::kPause), &cursor_location); GetEventGenerator()->MoveMouseTo(cursor_location); GetEventGenerator()->ClickLeftButton(); - Shell::Get()->media_notification_controller()->FlushForTesting(); + GetItem()->FlushForTesting(); EXPECT_EQ(1, media_controller()->suspend_count()); } @@ -288,7 +304,7 @@ GetButtonForAction(MediaSessionAction::kPreviousTrack), &cursor_location); GetEventGenerator()->MoveMouseTo(cursor_location); GetEventGenerator()->ClickLeftButton(); - Shell::Get()->media_notification_controller()->FlushForTesting(); + GetItem()->FlushForTesting(); EXPECT_EQ(1, media_controller()->previous_track_count()); } @@ -301,7 +317,7 @@ GetButtonForAction(MediaSessionAction::kSeekBackward), &cursor_location); GetEventGenerator()->MoveMouseTo(cursor_location); GetEventGenerator()->ClickLeftButton(); - Shell::Get()->media_notification_controller()->FlushForTesting(); + GetItem()->FlushForTesting(); EXPECT_EQ(1, media_controller()->seek_backward_count()); } @@ -314,7 +330,7 @@ GetButtonForAction(MediaSessionAction::kSeekForward), &cursor_location); GetEventGenerator()->MoveMouseTo(cursor_location); GetEventGenerator()->ClickLeftButton(); - Shell::Get()->media_notification_controller()->FlushForTesting(); + GetItem()->FlushForTesting(); EXPECT_EQ(1, media_controller()->seek_forward_count()); } @@ -326,7 +342,7 @@ views::View::ConvertPointToScreen(view(), &cursor_location); GetEventGenerator()->MoveMouseTo(cursor_location); GetEventGenerator()->ClickLeftButton(); - Shell::Get()->media_notification_controller()->FlushForTesting(); + GetItem()->FlushForTesting(); EXPECT_EQ(0, media_controller()->toggle_suspend_resume_count()); } @@ -339,8 +355,11 @@ EXPECT_FALSE(button->toggled_for_testing()); } - Shell::Get()->media_notification_controller()->OnActiveSessionChanged( - nullptr); + media_session::mojom::AudioFocusRequestStatePtr session( + media_session::mojom::AudioFocusRequestState::New()); + session->request_id = request_id(); + Shell::Get()->media_notification_controller()->OnFocusLost( + std::move(session)); // Disable the tray and run the loop to make sure that the existing view is // destroyed. @@ -370,7 +389,7 @@ ASSERT_EQ(views::ToggleImageButton::kViewClassName, button->GetClassName()); EXPECT_FALSE(button->toggled_for_testing()); - Shell::Get()->media_notification_controller()->MediaSessionInfoChanged( + GetItem()->MediaSessionInfoChanged( media_session::mojom::MediaSessionInfo::New()); EXPECT_FALSE(button->toggled_for_testing()); } @@ -386,14 +405,12 @@ session_info->playback_state = media_session::mojom::MediaPlaybackState::kPlaying; - Shell::Get()->media_notification_controller()->MediaSessionInfoChanged( - session_info.Clone()); + GetItem()->MediaSessionInfoChanged(session_info.Clone()); EXPECT_TRUE(button->toggled_for_testing()); session_info->playback_state = media_session::mojom::MediaPlaybackState::kPaused; - Shell::Get()->media_notification_controller()->MediaSessionInfoChanged( - session_info.Clone()); + GetItem()->MediaSessionInfoChanged(session_info.Clone()); EXPECT_FALSE(button->toggled_for_testing()); } @@ -404,8 +421,7 @@ TEST_F(MediaNotificationViewTest, UpdateMetadata_FromObserver_Empty) { UpdateWithSampleMetadata(); - Shell::Get()->media_notification_controller()->MediaSessionMetadataChanged( - base::nullopt); + GetItem()->MediaSessionMetadataChanged(base::nullopt); EXPECT_FALSE(title_artist_row()->visible()); } @@ -413,8 +429,7 @@ TEST_F(MediaNotificationViewTest, UpdateMetadata_FromObserver_EmptyString) { UpdateWithSampleMetadata(); - Shell::Get()->media_notification_controller()->MediaSessionMetadataChanged( - media_session::MediaMetadata()); + GetItem()->MediaSessionMetadataChanged(media_session::MediaMetadata()); EXPECT_FALSE(title_artist_row()->visible()); } @@ -427,8 +442,7 @@ media_session::MediaMetadata metadata; metadata.title = base::ASCIIToUTF16("title"); - Shell::Get()->media_notification_controller()->MediaSessionMetadataChanged( - metadata); + GetItem()->MediaSessionMetadataChanged(metadata); EXPECT_TRUE(title_artist_row()->visible()); EXPECT_TRUE(title_label()->visible()); @@ -445,8 +459,7 @@ media_session::MediaMetadata metadata; metadata.artist = base::ASCIIToUTF16("artist"); - Shell::Get()->media_notification_controller()->MediaSessionMetadataChanged( - metadata); + GetItem()->MediaSessionMetadataChanged(metadata); EXPECT_TRUE(title_artist_row()->visible()); EXPECT_FALSE(title_label()->visible()); @@ -459,8 +472,7 @@ media_session::MediaMetadata metadata; metadata.artist = base::ASCIIToUTF16("artist"); - Shell::Get()->media_notification_controller()->MediaSessionMetadataChanged( - metadata); + GetItem()->MediaSessionMetadataChanged(metadata); view()->SetExpanded(false); @@ -479,8 +491,7 @@ media_session::MediaMetadata metadata; metadata.artist = base::ASCIIToUTF16("artist"); - Shell::Get()->media_notification_controller()->MediaSessionMetadataChanged( - metadata); + GetItem()->MediaSessionMetadataChanged(metadata); view()->SetExpanded(true);
diff --git a/ash/media_controller.cc b/ash/media_controller.cc index 5e943f1..8727215 100644 --- a/ash/media_controller.cc +++ b/ash/media_controller.cc
@@ -101,8 +101,11 @@ MediaController::GetMediaSessionController() { // |connector_| can be null in tests. if (connector_ && !media_session_controller_ptr_.is_bound()) { + media_session::mojom::MediaControllerManagerPtr controller_manager_ptr; connector_->BindInterface(media_session::mojom::kServiceName, - &media_session_controller_ptr_); + &controller_manager_ptr); + controller_manager_ptr->CreateActiveMediaController( + mojo::MakeRequest(&media_session_controller_ptr_)); media_session_controller_ptr_.set_connection_error_handler( base::BindRepeating(&MediaController::OnMediaSessionControllerError,
diff --git a/ash/public/interfaces/assistant_controller.mojom b/ash/public/interfaces/assistant_controller.mojom index 2e15b4b8..47bef27 100644 --- a/ash/public/interfaces/assistant_controller.mojom +++ b/ash/public/interfaces/assistant_controller.mojom
@@ -24,6 +24,9 @@ // Opens Google Assistant settings. OpenAssistantSettings(); + + // Show speaker id enrollment flow. + StartSpeakerIdEnrollmentFlow(); }; // Interface to the AssistantAlarmTimerController which is owned by the @@ -78,4 +81,4 @@ // Provides an interface to the |assistant_setup| owned by AssistantClient // in chrome/browser. SetAssistantSetup(AssistantSetup assistant_setup); -}; \ No newline at end of file +};
diff --git a/ash/public/interfaces/assistant_setup.mojom b/ash/public/interfaces/assistant_setup.mojom index 38d3d18..2bc7d4f7 100644 --- a/ash/public/interfaces/assistant_setup.mojom +++ b/ash/public/interfaces/assistant_setup.mojom
@@ -4,10 +4,17 @@ module ash.mojom; +enum FlowType { + // The whole consent flow. + CONSENT_FLOW, + // The speaker id enrollment flow. + SPEAKER_ID_ENROLLMENT, +}; + // Interface for a class which is responsible for start Assistant OptIn flow. interface AssistantSetup { // Start the assistant setup flow. // |completed| is true if the user has completed the entire flow and opted in // to using assistant. - StartAssistantOptInFlow() => (bool completed); + StartAssistantOptInFlow(FlowType type) => (bool completed); };
diff --git a/ash/shelf/shelf_tooltip_manager.cc b/ash/shelf/shelf_tooltip_manager.cc index 7b451eb..3b5b728 100644 --- a/ash/shelf/shelf_tooltip_manager.cc +++ b/ash/shelf/shelf_tooltip_manager.cc
@@ -101,6 +101,8 @@ ::wm::SetWindowVisibilityAnimationType( window, ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL); ::wm::SetWindowVisibilityAnimationTransition(window, ::wm::ANIMATE_HIDE); + // Do not trigger a highlight when hovering over shelf items. + bubble_->set_highlight_button_when_shown(false); bubble_->GetWidget()->Show(); }
diff --git a/ash/strings/ash_strings_am.xtb b/ash/strings/ash_strings_am.xtb index 3a8311b..8a69c50 100644 --- a/ash/strings/ash_strings_am.xtb +++ b/ash/strings/ash_strings_am.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">መልዕክት ይተይቡ</translation> <translation id="2050339315714019657">በቁመት</translation> <translation id="2067602449040652523">የቁልፍ ሰሌዳ ብሩህነት</translation> -<translation id="2081529251031312395">$1 አሁንም በኋላ ላይ በመለያ መግባት ይችላሉ።</translation> <translation id="2127372758936585790">አነስተኛ ኃይል ያለው ባትሪ መሙያ</translation> <translation id="2135456203358955318">የተተከለ ማጉያ</translation> <translation id="2144487987174258011">Adobe Flash Playerን ለማዘመን ዳግም ያስጀምሩ</translation>
diff --git a/ash/strings/ash_strings_ar.xtb b/ash/strings/ash_strings_ar.xtb index 4df586da..e6dfec2 100644 --- a/ash/strings/ash_strings_ar.xtb +++ b/ash/strings/ash_strings_ar.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">كتابة رسالة</translation> <translation id="2050339315714019657">رأسي</translation> <translation id="2067602449040652523">سطوع لوحة المفاتيح</translation> -<translation id="2081529251031312395">سيظل بإمكان $1 تسجيل الدخول لاحقًا.</translation> <translation id="2127372758936585790">شاحن منخفض الطاقة</translation> <translation id="2135456203358955318">المكبّر الذي تم إرساؤه</translation> <translation id="2144487987174258011">إعادة التشغيل لتحديث Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_bg.xtb b/ash/strings/ash_strings_bg.xtb index a8626311..cbac834 100644 --- a/ash/strings/ash_strings_bg.xtb +++ b/ash/strings/ash_strings_bg.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Въведете съобщение</translation> <translation id="2050339315714019657">Вертикално</translation> <translation id="2067602449040652523">Яркост на клавиатурата</translation> -<translation id="2081529251031312395">$1 пак може да влезе в профила си по-късно.</translation> <translation id="2127372758936585790">Зарядно устройство с малка мощност</translation> <translation id="2135456203358955318">Лупа в прикрепен режим</translation> <translation id="2144487987174258011">Рестартирайте, за да актуализирате Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_bn.xtb b/ash/strings/ash_strings_bn.xtb index 2863d20d..44c97f7 100644 --- a/ash/strings/ash_strings_bn.xtb +++ b/ash/strings/ash_strings_bn.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">একটি মেসেজ লিখুন</translation> <translation id="2050339315714019657">প্রতিকৃতি</translation> <translation id="2067602449040652523">কীবোর্ডের উজ্জ্বলতা</translation> -<translation id="2081529251031312395">এখনও $1 পরে সাইন-ইন করতে পারেন।</translation> <translation id="2127372758936585790">নিম্ন শক্তির চার্জার</translation> <translation id="2135456203358955318">ডক করা ম্যাগনিফায়ার</translation> <translation id="2144487987174258011">Adobe ফ্ল্যাশ প্লেয়ার আপডেট করার জন্য বন্ধ করে আবার চালু করুন</translation>
diff --git a/ash/strings/ash_strings_ca.xtb b/ash/strings/ash_strings_ca.xtb index 8c3dcb2..b150e32a 100644 --- a/ash/strings/ash_strings_ca.xtb +++ b/ash/strings/ash_strings_ca.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Escriu un missatge</translation> <translation id="2050339315714019657">Vertical</translation> <translation id="2067602449040652523">Brillantor del teclat</translation> -<translation id="2081529251031312395">$1 pot iniciar la sessió més tard.</translation> <translation id="2127372758936585790">Carregador de baix consum</translation> <translation id="2135456203358955318">Lupa acoblada</translation> <translation id="2144487987174258011">Reinicia per actualitzar Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_cs.xtb b/ash/strings/ash_strings_cs.xtb index fca7c74..23e3201 100644 --- a/ash/strings/ash_strings_cs.xtb +++ b/ash/strings/ash_strings_cs.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Zadejte zprávu</translation> <translation id="2050339315714019657">Na výšku</translation> <translation id="2067602449040652523">Jas klávesnice</translation> -<translation id="2081529251031312395">$1 se bude moci později přihlásit.</translation> <translation id="2127372758936585790">Nabíječka má příliš nízký výkon</translation> <translation id="2135456203358955318">Zadokovaná lupa</translation> <translation id="2144487987174258011">Aktualizace přehrávače Adobe Flash Player vyžaduje restart</translation>
diff --git a/ash/strings/ash_strings_da.xtb b/ash/strings/ash_strings_da.xtb index ead2c478..c84f86cc 100644 --- a/ash/strings/ash_strings_da.xtb +++ b/ash/strings/ash_strings_da.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Skriv en besked</translation> <translation id="2050339315714019657">Stående</translation> <translation id="2067602449040652523">Lysstyrke for tastatur</translation> -<translation id="2081529251031312395">$1 kan stadig logge ind senere.</translation> <translation id="2127372758936585790">Oplader ved lav kraft</translation> <translation id="2135456203358955318">Fastgjort lupvindue</translation> <translation id="2144487987174258011">Genstart for at opdatere Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_de.xtb b/ash/strings/ash_strings_de.xtb index ba9dc69f..bb3393e 100644 --- a/ash/strings/ash_strings_de.xtb +++ b/ash/strings/ash_strings_de.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Nachricht eingeben</translation> <translation id="2050339315714019657">Hochformat</translation> <translation id="2067602449040652523">Tastaturhelligkeit</translation> -<translation id="2081529251031312395">$1 kann sich später weiterhin anmelden.</translation> <translation id="2127372758936585790">Schwachstrom-Ladegerät</translation> <translation id="2135456203358955318">Angedockte Lupe</translation> <translation id="2144487987174258011">Neu starten, um den Adobe Flash Player zu aktualisieren</translation>
diff --git a/ash/strings/ash_strings_el.xtb b/ash/strings/ash_strings_el.xtb index 4aedd40..edaabc3 100644 --- a/ash/strings/ash_strings_el.xtb +++ b/ash/strings/ash_strings_el.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Πληκτρολογήστε ένα μήνυμα</translation> <translation id="2050339315714019657">Κάθετα</translation> <translation id="2067602449040652523">Φωτεινότητα πληκτρολογίου</translation> -<translation id="2081529251031312395">Ο χρήστης $1 μπορεί να συνδεθεί αργότερα.</translation> <translation id="2127372758936585790">Χαμηλή ισχύς φορτιστή</translation> <translation id="2135456203358955318">Μεγεθυντικός φακός σε παράθυρο</translation> <translation id="2144487987174258011">Κάντε επανεκκίνηση για να ενημερώσετε το Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_en-GB.xtb b/ash/strings/ash_strings_en-GB.xtb index 81645e7..4d25119 100644 --- a/ash/strings/ash_strings_en-GB.xtb +++ b/ash/strings/ash_strings_en-GB.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Type a message</translation> <translation id="2050339315714019657">Portrait</translation> <translation id="2067602449040652523">Keyboard brightness</translation> -<translation id="2081529251031312395">$1 can still sign in later.</translation> <translation id="2127372758936585790">Low-power charger</translation> <translation id="2135456203358955318">Docked magnifier</translation> <translation id="2144487987174258011">Restart to update Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_es-419.xtb b/ash/strings/ash_strings_es-419.xtb index 79d4a58..1344d06b 100644 --- a/ash/strings/ash_strings_es-419.xtb +++ b/ash/strings/ash_strings_es-419.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Escribe un mensaje</translation> <translation id="2050339315714019657">Vertical</translation> <translation id="2067602449040652523">Brillo del teclado</translation> -<translation id="2081529251031312395">$1 podrá acceder más tarde.</translation> <translation id="2127372758936585790">Carga lenta</translation> <translation id="2135456203358955318">Lupa con vista acoplada</translation> <translation id="2144487987174258011">Reinicia para actualizar Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_es.xtb b/ash/strings/ash_strings_es.xtb index 2be0390..0a2af70 100644 --- a/ash/strings/ash_strings_es.xtb +++ b/ash/strings/ash_strings_es.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Escribe un mensaje</translation> <translation id="2050339315714019657">Vertical</translation> <translation id="2067602449040652523">Brillo del teclado</translation> -<translation id="2081529251031312395">$1 aún podrá iniciar sesión.</translation> <translation id="2127372758936585790">Carga lenta</translation> <translation id="2135456203358955318">Lupa fijada</translation> <translation id="2144487987174258011">Reinicia para actualizar Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_et.xtb b/ash/strings/ash_strings_et.xtb index 81cb0f0..399bee65 100644 --- a/ash/strings/ash_strings_et.xtb +++ b/ash/strings/ash_strings_et.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Sisestage sõnum</translation> <translation id="2050339315714019657">Vertikaalpaigutus</translation> <translation id="2067602449040652523">Klaviatuuri eredus</translation> -<translation id="2081529251031312395">$1 saab siiski hiljem sisse logida.</translation> <translation id="2127372758936585790">Väikese energiakuluga laadija</translation> <translation id="2135456203358955318">Dokitud luup</translation> <translation id="2144487987174258011">Taaskäivitage Adobe Flash Playeri värskendamiseks</translation>
diff --git a/ash/strings/ash_strings_fa.xtb b/ash/strings/ash_strings_fa.xtb index a857d697..96bf78b 100644 --- a/ash/strings/ash_strings_fa.xtb +++ b/ash/strings/ash_strings_fa.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">پیامی تایپ کنید</translation> <translation id="2050339315714019657">عمودی</translation> <translation id="2067602449040652523">روشنایی صفحهکلید</translation> -<translation id="2081529251031312395">$1 همچنان میتواند بعداً به سیستم وارد شود.</translation> <translation id="2127372758936585790">شارژر برق ضعیف</translation> <translation id="2135456203358955318">ذرهبین متصل</translation> <translation id="2144487987174258011">برای بهروزرسانی Adobe Flash Player، راهاندازی مجدد کنید</translation>
diff --git a/ash/strings/ash_strings_fi.xtb b/ash/strings/ash_strings_fi.xtb index b9ac6fd..5a01c0d4 100644 --- a/ash/strings/ash_strings_fi.xtb +++ b/ash/strings/ash_strings_fi.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Kirjoita viesti</translation> <translation id="2050339315714019657">Pystysuunta</translation> <translation id="2067602449040652523">Näppäimistön kirkkaus</translation> -<translation id="2081529251031312395">$1 voi silti kirjautua sisään myöhemmin.</translation> <translation id="2127372758936585790">Pienitehoinen laturi</translation> <translation id="2135456203358955318">Kiinnitetty suurennus</translation> <translation id="2144487987174258011">Päivitä Adobe Flash Player käynnistämällä uudelleen.</translation>
diff --git a/ash/strings/ash_strings_fil.xtb b/ash/strings/ash_strings_fil.xtb index 28926f3..6484f49 100644 --- a/ash/strings/ash_strings_fil.xtb +++ b/ash/strings/ash_strings_fil.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Mag-type ng mensahe</translation> <translation id="2050339315714019657">Portrait</translation> <translation id="2067602449040652523">Liwanag ng keyboard</translation> -<translation id="2081529251031312395">Maaari pa ring mag-sign in si $1 sa ibang pagkakataon.</translation> <translation id="2127372758936585790">Low-power charger</translation> <translation id="2135456203358955318">Naka-dock na magnifier</translation> <translation id="2144487987174258011">I-restart upang i-update ang Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_fr.xtb b/ash/strings/ash_strings_fr.xtb index 24bb668e..bcf62310 100644 --- a/ash/strings/ash_strings_fr.xtb +++ b/ash/strings/ash_strings_fr.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Saisissez un message</translation> <translation id="2050339315714019657">Portrait</translation> <translation id="2067602449040652523">Luminosité du clavier</translation> -<translation id="2081529251031312395">$1 pourra toujours se connecter plus tard.</translation> <translation id="2127372758936585790">Chargeur de faible puissance</translation> <translation id="2135456203358955318">Loupe ancrée</translation> <translation id="2144487987174258011">Redémarrez pour mettre Adobe Flash Player à jour</translation>
diff --git a/ash/strings/ash_strings_gu.xtb b/ash/strings/ash_strings_gu.xtb index fa6d99d6..11b6d5c8 100644 --- a/ash/strings/ash_strings_gu.xtb +++ b/ash/strings/ash_strings_gu.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">એક સંદેશ લખો</translation> <translation id="2050339315714019657">પોર્ટ્રેટ</translation> <translation id="2067602449040652523">કીબોર્ડનું તેજ</translation> -<translation id="2081529251031312395">$1 હજુ થોડા સમય પછી સાઇન ઇન કરી શકશે.</translation> <translation id="2127372758936585790">નિમ્ન-પાવર ચાર્જર</translation> <translation id="2135456203358955318">ડૉક કરેલ મૅગ્નિફાયર</translation> <translation id="2144487987174258011">Adobe Flash Player અપડેટ કરવા પુનઃપ્રારંભ કરો</translation>
diff --git a/ash/strings/ash_strings_hi.xtb b/ash/strings/ash_strings_hi.xtb index 00c2d8a..5d833a9c 100644 --- a/ash/strings/ash_strings_hi.xtb +++ b/ash/strings/ash_strings_hi.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">कोई मैसेज लिखें</translation> <translation id="2050339315714019657">पोर्ट्रेट</translation> <translation id="2067602449040652523">कीबोर्ड की रोशनी</translation> -<translation id="2081529251031312395">$1 अभी भी बाद में साइन इन कर सकता है.</translation> <translation id="2127372758936585790">कम-शक्ति वाला चार्जर</translation> <translation id="2135456203358955318">सामग्री को बड़ा दिखाने की डॉक की गई सुविधा</translation> <translation id="2144487987174258011">Adobe Flash Player को अपडेट करने के लिए फिर से चालू करें</translation>
diff --git a/ash/strings/ash_strings_hr.xtb b/ash/strings/ash_strings_hr.xtb index 63987ca6..fd25320 100644 --- a/ash/strings/ash_strings_hr.xtb +++ b/ash/strings/ash_strings_hr.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Unesite poruku</translation> <translation id="2050339315714019657">Portret</translation> <translation id="2067602449040652523">Svjetlina tipkovnice</translation> -<translation id="2081529251031312395">Korisnik $1 može se prijaviti i kasnije.</translation> <translation id="2127372758936585790">Punjač male snage</translation> <translation id="2135456203358955318">Usidreno povećalo</translation> <translation id="2144487987174258011">Ponovno pokrenite da biste ažurirali Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_hu.xtb b/ash/strings/ash_strings_hu.xtb index e8ca72f..9375051 100644 --- a/ash/strings/ash_strings_hu.xtb +++ b/ash/strings/ash_strings_hu.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Írja be az üzenetet</translation> <translation id="2050339315714019657">Álló</translation> <translation id="2067602449040652523">Billentyűzet világossága</translation> -<translation id="2081529251031312395">$1 később be tud jelentkezni.</translation> <translation id="2127372758936585790">Kis teljesítményű töltő</translation> <translation id="2135456203358955318">Dokkolt nagyító</translation> <translation id="2144487987174258011">Az Adobe Flash Player frissítéséhez újraindítás szükséges</translation>
diff --git a/ash/strings/ash_strings_id.xtb b/ash/strings/ash_strings_id.xtb index 02780f2..2a40171 100644 --- a/ash/strings/ash_strings_id.xtb +++ b/ash/strings/ash_strings_id.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Ketik pesan</translation> <translation id="2050339315714019657">Potret</translation> <translation id="2067602449040652523">Kecerahan keyboard</translation> -<translation id="2081529251031312395">$1 tetap dapat login nanti.</translation> <translation id="2127372758936585790">Pengisi daya rendah</translation> <translation id="2135456203358955318">Kaca pembesar yang dipasang ke dok</translation> <translation id="2144487987174258011">Nyalakan ulang untuk mengupdate Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_it.xtb b/ash/strings/ash_strings_it.xtb index d369b969..9824c8d 100644 --- a/ash/strings/ash_strings_it.xtb +++ b/ash/strings/ash_strings_it.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Digita un messaggio</translation> <translation id="2050339315714019657">Verticale</translation> <translation id="2067602449040652523">Luminosità della tastiera</translation> -<translation id="2081529251031312395">$1 può accedere in seguito.</translation> <translation id="2127372758936585790">Caricabatterie a basso consumo</translation> <translation id="2135456203358955318">Lente d'ingrandimento ancorata</translation> <translation id="2144487987174258011">Riavvia per aggiornare Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_iw.xtb b/ash/strings/ash_strings_iw.xtb index 8ae3100..719497d0 100644 --- a/ash/strings/ash_strings_iw.xtb +++ b/ash/strings/ash_strings_iw.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">כאן מקלידים את ההודעה</translation> <translation id="2050339315714019657">לאורך</translation> <translation id="2067602449040652523">בהירות מקלדת</translation> -<translation id="2081529251031312395">ל-$1 עדיין תהיה אפשרות להיכנס מאוחר יותר.</translation> <translation id="2127372758936585790">מטען בעל מתח נמוך</translation> <translation id="2135456203358955318">מגדיל במצב מעוגן</translation> <translation id="2144487987174258011">הפעל מחדש כדי לעדכן את Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_ja.xtb b/ash/strings/ash_strings_ja.xtb index 68e3eb9..f5c6842 100644 --- a/ash/strings/ash_strings_ja.xtb +++ b/ash/strings/ash_strings_ja.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">メッセージを入力</translation> <translation id="2050339315714019657">縦</translation> <translation id="2067602449040652523">キーボードの明るさ</translation> -<translation id="2081529251031312395">$1 が後でログインすることは引き続き可能です。</translation> <translation id="2127372758936585790">低電力の充電器</translation> <translation id="2135456203358955318">拡大鏡(ドッキング)</translation> <translation id="2144487987174258011">Adobe Flash Player を更新するには再起動してください</translation>
diff --git a/ash/strings/ash_strings_kn.xtb b/ash/strings/ash_strings_kn.xtb index 24ad1ce9f..d5cf802 100644 --- a/ash/strings/ash_strings_kn.xtb +++ b/ash/strings/ash_strings_kn.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">ಸಂದೇಶವನ್ನು ಟೈಪ್ ಮಾಡಿ</translation> <translation id="2050339315714019657">ಪೋಟ್ರೇಟ್</translation> <translation id="2067602449040652523">ಕೀಬೋರ್ಡ್ ಪ್ರಖರತೆ</translation> -<translation id="2081529251031312395">$1 ಆನಂತರವೂ ಸೈನ್ ಇನ್ ಮಾಡಬಹುದು.</translation> <translation id="2127372758936585790">ಕಡಿಮೆ ವಿದ್ಯುತ್ ಚಾರ್ಜರ್</translation> <translation id="2135456203358955318">ಡಾಕ್ ಮಾಡಿರುವ ವರ್ಧಕ</translation> <translation id="2144487987174258011">Adobe Flash Player ಅಪ್ಡೇಟ್ ಮಾಡಲು ಮರುಪ್ರಾರಂಭಿಸಿ</translation>
diff --git a/ash/strings/ash_strings_ko.xtb b/ash/strings/ash_strings_ko.xtb index c80a4c1..e4a69bc8e 100644 --- a/ash/strings/ash_strings_ko.xtb +++ b/ash/strings/ash_strings_ko.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">메시지 입력</translation> <translation id="2050339315714019657">세로 방향</translation> <translation id="2067602449040652523">키보드 밝기</translation> -<translation id="2081529251031312395">$1님이 나중에 로그인할 수 있습니다.</translation> <translation id="2127372758936585790">저출력 충전기</translation> <translation id="2135456203358955318">고정 돋보기</translation> <translation id="2144487987174258011">Adobe Flash Player를 업데이트하려면 다시 시작하세요.</translation>
diff --git a/ash/strings/ash_strings_lt.xtb b/ash/strings/ash_strings_lt.xtb index b2e0545..e8b9803 100644 --- a/ash/strings/ash_strings_lt.xtb +++ b/ash/strings/ash_strings_lt.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Įveskite pranešimą</translation> <translation id="2050339315714019657">Stačias</translation> <translation id="2067602449040652523">Klaviatūros šviesumas</translation> -<translation id="2081529251031312395">$1 vis tiek galės vėliau prisijungti.</translation> <translation id="2127372758936585790">Mažos galios įkroviklis</translation> <translation id="2135456203358955318">Prie doko prijungtas didintuvas</translation> <translation id="2144487987174258011">Paleiskite iš naujo, kad atnaujintumėte „Adobe Flash Player“</translation>
diff --git a/ash/strings/ash_strings_lv.xtb b/ash/strings/ash_strings_lv.xtb index 59529aad..c07d146 100644 --- a/ash/strings/ash_strings_lv.xtb +++ b/ash/strings/ash_strings_lv.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Ierakstiet ziņojumu</translation> <translation id="2050339315714019657">Portrets</translation> <translation id="2067602449040652523">Tastatūras spilgtums</translation> -<translation id="2081529251031312395">$1 joprojām varēs pierakstīties vēlāk.</translation> <translation id="2127372758936585790">Lādētājs ar mazu strāvas padevi</translation> <translation id="2135456203358955318">Dokota lupa</translation> <translation id="2144487987174258011">Restartējiet, lai atjauninātu Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_ml.xtb b/ash/strings/ash_strings_ml.xtb index 124f37c..f0fa1fc 100644 --- a/ash/strings/ash_strings_ml.xtb +++ b/ash/strings/ash_strings_ml.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">ഒരു സന്ദേശം ടൈപ്പ് ചെയ്യുക</translation> <translation id="2050339315714019657">ഛായാചിത്രം</translation> <translation id="2067602449040652523">കീബോർഡ് തെളിച്ചം</translation> -<translation id="2081529251031312395">$1 എന്ന വ്യക്തിക്ക് പിന്നീട് സൈൻ ഇൻ ചെയ്യാവുന്നതാണ്.</translation> <translation id="2127372758936585790">കുറഞ്ഞ തോതിൽ വൈദ്യുതി പ്രവഹിക്കുന്ന ചാർജർ</translation> <translation id="2135456203358955318">ഡോക്ക് ചെയ്ത മാഗ്നിഫയർ</translation> <translation id="2144487987174258011">Adobe Flash Player അപ്ഡേറ്റുചെയ്യാൻ പുനരാരംഭിക്കുക</translation>
diff --git a/ash/strings/ash_strings_mr.xtb b/ash/strings/ash_strings_mr.xtb index bc9446d6..177ec1d 100644 --- a/ash/strings/ash_strings_mr.xtb +++ b/ash/strings/ash_strings_mr.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">मेसेज टाइप करा</translation> <translation id="2050339315714019657">पोर्ट्रेट</translation> <translation id="2067602449040652523">कीबोर्डची चमक</translation> -<translation id="2081529251031312395">$1 नंतरही साइन इन करू शकतो.</translation> <translation id="2127372758936585790">निम्न-उर्जेचे चार्जर</translation> <translation id="2135456203358955318">डॉक केलेले भिंग</translation> <translation id="2144487987174258011">Adobe Flash Player अपडेट करण्यासाठी पुन्हा सुरू करा</translation>
diff --git a/ash/strings/ash_strings_ms.xtb b/ash/strings/ash_strings_ms.xtb index c4eab2e..a7561ae3 100644 --- a/ash/strings/ash_strings_ms.xtb +++ b/ash/strings/ash_strings_ms.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Taip mesej</translation> <translation id="2050339315714019657">Potret</translation> <translation id="2067602449040652523">Kecerahan papan kekunci</translation> -<translation id="2081529251031312395">$1 masih dapat log masuk nanti.</translation> <translation id="2127372758936585790">Pengecas berkuasa rendah</translation> <translation id="2135456203358955318">Penggadang didok</translation> <translation id="2144487987174258011">Mulakan semula untuk mengemas kini Pemain Adobe Flash</translation>
diff --git a/ash/strings/ash_strings_nl.xtb b/ash/strings/ash_strings_nl.xtb index 799d3413..59136dc 100644 --- a/ash/strings/ash_strings_nl.xtb +++ b/ash/strings/ash_strings_nl.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Typ een bericht</translation> <translation id="2050339315714019657">Staand</translation> <translation id="2067602449040652523">Toetsenbordhelderheid</translation> -<translation id="2081529251031312395">$1 kan later nog inloggen.</translation> <translation id="2127372758936585790">Laag-vermogen-lader</translation> <translation id="2135456203358955318">Gedockt vergrootglas</translation> <translation id="2144487987174258011">Start opnieuw op om Adobe Flash Player te updaten</translation>
diff --git a/ash/strings/ash_strings_no.xtb b/ash/strings/ash_strings_no.xtb index b2aa384..8d9befdd 100644 --- a/ash/strings/ash_strings_no.xtb +++ b/ash/strings/ash_strings_no.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Skriv inn en melding</translation> <translation id="2050339315714019657">Stående</translation> <translation id="2067602449040652523">Lysstyrke på tastaturet</translation> -<translation id="2081529251031312395">$1 kan likevel logge på senere.</translation> <translation id="2127372758936585790">Lading med lav effekt</translation> <translation id="2135456203358955318">Dokket lupe</translation> <translation id="2144487987174258011">Start på nytt for å oppdatere Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_pl.xtb b/ash/strings/ash_strings_pl.xtb index 4feb2fd..4d5b47d 100644 --- a/ash/strings/ash_strings_pl.xtb +++ b/ash/strings/ash_strings_pl.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Wpisz wiadomość</translation> <translation id="2050339315714019657">Pionowo</translation> <translation id="2067602449040652523">Jasność klawiatury</translation> -<translation id="2081529251031312395">$1 może się wciąż zalogować później.</translation> <translation id="2127372758936585790">Ładowarka o małej mocy</translation> <translation id="2135456203358955318">Lupa zadokowana</translation> <translation id="2144487987174258011">Uruchom ponownie, by zaktualizować Adobe Flash Playera</translation>
diff --git a/ash/strings/ash_strings_pt-BR.xtb b/ash/strings/ash_strings_pt-BR.xtb index 31fa3eb..8e4fe8a 100644 --- a/ash/strings/ash_strings_pt-BR.xtb +++ b/ash/strings/ash_strings_pt-BR.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Digite uma mensagem</translation> <translation id="2050339315714019657">Retrato</translation> <translation id="2067602449040652523">Brilho do teclado</translation> -<translation id="2081529251031312395">$1 ainda pode fazer login mais tarde.</translation> <translation id="2127372758936585790">Carregador de baixa potência</translation> <translation id="2135456203358955318">Lupa ancorada</translation> <translation id="2144487987174258011">Reinicie para atualizar o Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_pt-PT.xtb b/ash/strings/ash_strings_pt-PT.xtb index c68133d..12f92bb 100644 --- a/ash/strings/ash_strings_pt-PT.xtb +++ b/ash/strings/ash_strings_pt-PT.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Escrever uma mensagem</translation> <translation id="2050339315714019657">Vertical</translation> <translation id="2067602449040652523">Brilho do teclado</translation> -<translation id="2081529251031312395">$1 pode iniciar sessão mais tarde.</translation> <translation id="2127372758936585790">Carregador de baixo consumo</translation> <translation id="2135456203358955318">Lupa ancorada</translation> <translation id="2144487987174258011">Reinicie para atualizar o Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_ro.xtb b/ash/strings/ash_strings_ro.xtb index be34791..bc04726c 100644 --- a/ash/strings/ash_strings_ro.xtb +++ b/ash/strings/ash_strings_ro.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Scrie un mesaj</translation> <translation id="2050339315714019657">Portret</translation> <translation id="2067602449040652523">Luminozitatea tastaturii</translation> -<translation id="2081529251031312395">$1 se poate conecta și mai târziu.</translation> <translation id="2127372758936585790">Încărcător de putere joasă</translation> <translation id="2135456203358955318">Lupă andocată</translation> <translation id="2144487987174258011">Repornește ca să actualizezi Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_ru.xtb b/ash/strings/ash_strings_ru.xtb index 9ed65d6..76ef9dc 100644 --- a/ash/strings/ash_strings_ru.xtb +++ b/ash/strings/ash_strings_ru.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Введите сообщение</translation> <translation id="2050339315714019657">Книжная</translation> <translation id="2067602449040652523">Яркость клавиатуры</translation> -<translation id="2081529251031312395">$1 может войти в аккаунт позже.</translation> <translation id="2127372758936585790">Маломощное зарядное устройство</translation> <translation id="2135456203358955318">Закрепленная лупа</translation> <translation id="2144487987174258011">Перезагрузите, чтобы обновить Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_sk.xtb b/ash/strings/ash_strings_sk.xtb index 9170029..48e4b45 100644 --- a/ash/strings/ash_strings_sk.xtb +++ b/ash/strings/ash_strings_sk.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Zadajte správu</translation> <translation id="2050339315714019657">Na výšku</translation> <translation id="2067602449040652523">Jas klávesnice</translation> -<translation id="2081529251031312395">$1 sa bude môcť stále prihlásiť neskôr.</translation> <translation id="2127372758936585790">Nabíjačka s nízkym výkonom</translation> <translation id="2135456203358955318">Ukotvená lupa</translation> <translation id="2144487987174258011">Reštartujte a aktualizujte tak Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_sl.xtb b/ash/strings/ash_strings_sl.xtb index f143d49..8943a2b 100644 --- a/ash/strings/ash_strings_sl.xtb +++ b/ash/strings/ash_strings_sl.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Vnesite sporočilo</translation> <translation id="2050339315714019657">Pokončno</translation> <translation id="2067602449040652523">Svetlost tipkovnice</translation> -<translation id="2081529251031312395">$1 se še vedno lahko prijavi pozneje.</translation> <translation id="2127372758936585790">Nizkoenergijski polnilnik</translation> <translation id="2135456203358955318">Zasidrana lupa</translation> <translation id="2144487987174258011">Če želite posodobiti Adobe Flash Player, znova zaženite</translation>
diff --git a/ash/strings/ash_strings_sr.xtb b/ash/strings/ash_strings_sr.xtb index ae194819..f7f12eb 100644 --- a/ash/strings/ash_strings_sr.xtb +++ b/ash/strings/ash_strings_sr.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Унесите поруку</translation> <translation id="2050339315714019657">Вертикално</translation> <translation id="2067602449040652523">Осветљеност тастатуре</translation> -<translation id="2081529251031312395">$1 ће и даље моћи да се пријави касније.</translation> <translation id="2127372758936585790">Пуњач мале снаге</translation> <translation id="2135456203358955318">Монтирана лупа екрана</translation> <translation id="2144487987174258011">Покрените поново да бисте ажурирали Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_sv.xtb b/ash/strings/ash_strings_sv.xtb index a8afb48..2d47f7c 100644 --- a/ash/strings/ash_strings_sv.xtb +++ b/ash/strings/ash_strings_sv.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Skriv ett meddelande</translation> <translation id="2050339315714019657">Stående</translation> <translation id="2067602449040652523">Ljusstyrka för tangentbordet</translation> -<translation id="2081529251031312395">$1 kan fortfarande logga in senare.</translation> <translation id="2127372758936585790">Laddning med låg effekt</translation> <translation id="2135456203358955318">Dockad skärmförstoring</translation> <translation id="2144487987174258011">Starta om för att uppdatera Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_sw.xtb b/ash/strings/ash_strings_sw.xtb index a950792b..a93b2c5 100644 --- a/ash/strings/ash_strings_sw.xtb +++ b/ash/strings/ash_strings_sw.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Andika ujumbe</translation> <translation id="2050339315714019657">Wima</translation> <translation id="2067602449040652523">Ung'avu wa kibodi</translation> -<translation id="2081529251031312395">Bado $1 anaweza kuingia katika akaunti baadaye.</translation> <translation id="2127372758936585790">Chaja ya nguvu ya chini</translation> <translation id="2135456203358955318">Kikuzaji kilichofungwa</translation> <translation id="2144487987174258011">Zima kisha uwashe ili usasishe Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_ta.xtb b/ash/strings/ash_strings_ta.xtb index 3d6ecec..ae319dac 100644 --- a/ash/strings/ash_strings_ta.xtb +++ b/ash/strings/ash_strings_ta.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">செய்தியை உள்ளிடவும்</translation> <translation id="2050339315714019657">செங்குத்து நிலை</translation> <translation id="2067602449040652523">விசைப்பலகை ஒளிர்வு</translation> -<translation id="2081529251031312395">$1 ஆல் பிறகு உள்நுழைய முடியும்.</translation> <translation id="2127372758936585790">குறைந்த சக்திகொண்ட சார்ஜர்</translation> <translation id="2135456203358955318">டாக் செய்யப்பட்ட பெரிதாக்கி</translation> <translation id="2144487987174258011">Adobe Flash Playerஐப் புதுப்பிக்க, மீண்டும் தொடங்கவும்</translation>
diff --git a/ash/strings/ash_strings_te.xtb b/ash/strings/ash_strings_te.xtb index 8faf7c5..8f7e949 100644 --- a/ash/strings/ash_strings_te.xtb +++ b/ash/strings/ash_strings_te.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">సందేశాన్ని టైప్ చేయండి</translation> <translation id="2050339315714019657">నిలువు</translation> <translation id="2067602449040652523">కీబోర్డ్ ప్రకాశం</translation> -<translation id="2081529251031312395">ఇప్పటికీ $1 తర్వాత సైన్ ఇన్ చేయవచ్చు.</translation> <translation id="2127372758936585790">తక్కువ-పవర్ గల ఛార్జర్</translation> <translation id="2135456203358955318">డాక్ చేయబడిన మాగ్నిఫైయర్</translation> <translation id="2144487987174258011">Adobe Flash Playerని అప్డేట్ చేయడానికి పున:ప్రారంభించండి</translation>
diff --git a/ash/strings/ash_strings_th.xtb b/ash/strings/ash_strings_th.xtb index fd05303..34c592dd 100644 --- a/ash/strings/ash_strings_th.xtb +++ b/ash/strings/ash_strings_th.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">พิมพ์ข้อความ</translation> <translation id="2050339315714019657">แนวตั้ง</translation> <translation id="2067602449040652523">ความสว่างของแป้นพิมพ์</translation> -<translation id="2081529251031312395">$1 ยังมีสิทธิ์ลงชื่อเข้าใช้ภายหลังได้</translation> <translation id="2127372758936585790">ที่ชาร์จพลังงานต่ำ</translation> <translation id="2135456203358955318">แว่นขยายหน้าจอบางส่วน</translation> <translation id="2144487987174258011">รีสตาร์ทเพื่ออัปเดต Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_tr.xtb b/ash/strings/ash_strings_tr.xtb index 4c2d025..bf729a1 100644 --- a/ash/strings/ash_strings_tr.xtb +++ b/ash/strings/ash_strings_tr.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Mesaj yazın</translation> <translation id="2050339315714019657">Dikey</translation> <translation id="2067602449040652523">Klavye parlaklığı</translation> -<translation id="2081529251031312395">$1 daha sonra yine oturum açabilir.</translation> <translation id="2127372758936585790">Düşük güçlü şarj cihazı</translation> <translation id="2135456203358955318">Yerleştirilmiş büyüteç</translation> <translation id="2144487987174258011">Adobe Flash Player'ı güncellemek için yeniden başlatın</translation>
diff --git a/ash/strings/ash_strings_uk.xtb b/ash/strings/ash_strings_uk.xtb index c08c09e2..b96ed41 100644 --- a/ash/strings/ash_strings_uk.xtb +++ b/ash/strings/ash_strings_uk.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Введіть повідомлення</translation> <translation id="2050339315714019657">Портретна</translation> <translation id="2067602449040652523">Яскравість клавіатури</translation> -<translation id="2081529251031312395">$1 усе одно зможе ввійти в обліковий запис.</translation> <translation id="2127372758936585790">Зарядний пристрій низької потужності</translation> <translation id="2135456203358955318">Закріплена лупа</translation> <translation id="2144487987174258011">Перезапустіть Chrome, щоб оновити Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_vi.xtb b/ash/strings/ash_strings_vi.xtb index 91029969..30bcc76 100644 --- a/ash/strings/ash_strings_vi.xtb +++ b/ash/strings/ash_strings_vi.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">Nhập tin nhắn</translation> <translation id="2050339315714019657">Khổ dọc</translation> <translation id="2067602449040652523">Độ sáng bàn phím</translation> -<translation id="2081529251031312395">$1 vẫn có thể đăng nhập sau.</translation> <translation id="2127372758936585790">Bộ sạc công suất thấp</translation> <translation id="2135456203358955318">Phóng to ở vị trí cố định</translation> <translation id="2144487987174258011">Khởi động lại để cập nhật Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_zh-CN.xtb b/ash/strings/ash_strings_zh-CN.xtb index 3abf8f6..3d988f5f 100644 --- a/ash/strings/ash_strings_zh-CN.xtb +++ b/ash/strings/ash_strings_zh-CN.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">请输入消息</translation> <translation id="2050339315714019657">纵向</translation> <translation id="2067602449040652523">键盘亮度</translation> -<translation id="2081529251031312395">日后“$1”仍能登录。</translation> <translation id="2127372758936585790">低功率充电器</translation> <translation id="2135456203358955318">停靠的放大镜</translation> <translation id="2144487987174258011">请重新启动以更新 Adobe Flash Player</translation>
diff --git a/ash/strings/ash_strings_zh-TW.xtb b/ash/strings/ash_strings_zh-TW.xtb index 31640a7f..4cdbade7 100644 --- a/ash/strings/ash_strings_zh-TW.xtb +++ b/ash/strings/ash_strings_zh-TW.xtb
@@ -72,7 +72,6 @@ <translation id="2016340657076538683">輸入訊息</translation> <translation id="2050339315714019657">縱向</translation> <translation id="2067602449040652523">鍵盤亮度</translation> -<translation id="2081529251031312395">「$1」日後仍可登入。</translation> <translation id="2127372758936585790">低功率充電器</translation> <translation id="2135456203358955318">停駐放大鏡</translation> <translation id="2144487987174258011">重新啟動以便更新 Adobe Flash Player</translation>
diff --git a/ash/system/power/power_prefs.cc b/ash/system/power/power_prefs.cc index 0631b30..83d9c34 100644 --- a/ash/system/power/power_prefs.cc +++ b/ash/system/power/power_prefs.cc
@@ -12,6 +12,7 @@ #include "base/bind.h" #include "base/callback.h" #include "base/time/default_tick_clock.h" +#include "chromeos/chromeos_features.h" #include "chromeos/dbus/power_manager/idle.pb.h" #include "chromeos/dbus/power_policy_controller.h" #include "components/pref_registry/pref_registry_syncable.h" @@ -259,15 +260,26 @@ prefs->GetBoolean(prefs::kPowerAllowScreenWakeLocks); values.enable_auto_screen_lock = prefs->GetBoolean(prefs::kEnableAutoScreenLock); - values.presentation_screen_dim_delay_factor = - prefs->GetDouble(prefs::kPowerPresentationScreenDimDelayFactor); - values.user_activity_screen_dim_delay_factor = - prefs->GetDouble(prefs::kPowerUserActivityScreenDimDelayFactor); + + // Screen-dim deferral in response to user activity predictions can interact + // poorly with delay scaling, resulting in the system staying awake for a long + // time if a prediction is wrong. https://crbug.com/888392. + if (prefs->GetBoolean(prefs::kPowerSmartDimEnabled) && + base::FeatureList::IsEnabled( + chromeos::features::kUserActivityPrediction)) { + values.presentation_screen_dim_delay_factor = 1.0; + values.user_activity_screen_dim_delay_factor = 1.0; + } else { + values.presentation_screen_dim_delay_factor = + prefs->GetDouble(prefs::kPowerPresentationScreenDimDelayFactor); + values.user_activity_screen_dim_delay_factor = + prefs->GetDouble(prefs::kPowerUserActivityScreenDimDelayFactor); + } + values.wait_for_initial_user_activity = prefs->GetBoolean(prefs::kPowerWaitForInitialUserActivity); values.force_nonzero_brightness_for_user_activity = prefs->GetBoolean(prefs::kPowerForceNonzeroBrightnessForUserActivity); - values.smart_dim_enabled = prefs->GetBoolean(prefs::kPowerSmartDimEnabled); power_policy_controller_->ApplyPrefs(values); }
diff --git a/base/BUILD.gn b/base/BUILD.gn index 699d42f4..0273b50b 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -191,6 +191,7 @@ "containers/stack.h", "containers/stack_container.h", "containers/unique_ptr_adapters.h", + "containers/util.h", "containers/vector_buffer.h", "cpu.cc", "cpu.h",
diff --git a/base/android/java/src/org/chromium/base/task/SingleThreadTaskRunner.java b/base/android/java/src/org/chromium/base/task/SingleThreadTaskRunner.java index b72e6e1..030c6df 100644 --- a/base/android/java/src/org/chromium/base/task/SingleThreadTaskRunner.java +++ b/base/android/java/src/org/chromium/base/task/SingleThreadTaskRunner.java
@@ -10,4 +10,10 @@ * unless specified otherwise by the provider of a given SingleThreadTaskRunner there are * no ordering guarantees w.r.t. other SingleThreadTaskRunner. */ -public interface SingleThreadTaskRunner extends SequencedTaskRunner {} +public interface SingleThreadTaskRunner extends SequencedTaskRunner { + /** + * + * @return true iff this SingleThreadTaskRunner is bound to the current thread. + */ + public boolean belongsToCurrentThread(); +}
diff --git a/base/android/java/src/org/chromium/base/task/SingleThreadTaskRunnerImpl.java b/base/android/java/src/org/chromium/base/task/SingleThreadTaskRunnerImpl.java index 51633a7..9fa78d5 100644 --- a/base/android/java/src/org/chromium/base/task/SingleThreadTaskRunnerImpl.java +++ b/base/android/java/src/org/chromium/base/task/SingleThreadTaskRunnerImpl.java
@@ -67,6 +67,15 @@ } } + @Override + public boolean belongsToCurrentThread() { + if (mNativeTaskRunnerAndroid != 0) + return nativeBelongsToCurrentThread(mNativeTaskRunnerAndroid); + if (mHandler != null) return mHandler.getLooper().getThread() == Thread.currentThread(); + assert (false); + return false; + } + private class PreNativeImpl extends PreNativeSequence { PreNativeImpl() { super("SingleThreadTaskRunnerImpl.PreNativeImpl.run"); @@ -97,4 +106,5 @@ boolean mayBlock, byte extensionId, byte[] extensionData); private native void nativeFinalize(long nativeTaskRunnerAndroid); private native void nativePostTask(long nativeTaskRunnerAndroid, Runnable task); + private native boolean nativeBelongsToCurrentThread(long nativeTaskRunnerAndroid); }
diff --git a/base/android/javatests/src/org/chromium/base/task/SingleThreadTaskRunnerImplTest.java b/base/android/javatests/src/org/chromium/base/task/SingleThreadTaskRunnerImplTest.java index dacc77ed..8756841b5 100644 --- a/base/android/javatests/src/org/chromium/base/task/SingleThreadTaskRunnerImplTest.java +++ b/base/android/javatests/src/org/chromium/base/task/SingleThreadTaskRunnerImplTest.java
@@ -15,6 +15,7 @@ import android.support.test.filters.SmallTest; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -70,4 +71,19 @@ SchedulerTestHelpers.preNativeRunUntilIdle(mHandlerThread); assertThat(orderList, contains(1, 2, 3)); } + + @Test + @SmallTest + public void testBelongsToCurrentThread() { + // The handler created during test setup belongs to a different thread. + SingleThreadTaskRunner taskQueue = + new SingleThreadTaskRunnerImpl(mHandler, new TaskTraits()); + Assert.assertFalse(taskQueue.belongsToCurrentThread()); + + // We create a handler belonging to current thread. + Looper.prepare(); + SingleThreadTaskRunner taskQueueCurrentThread = + new SingleThreadTaskRunnerImpl(new Handler(), new TaskTraits()); + Assert.assertTrue(taskQueueCurrentThread.belongsToCurrentThread()); + } }
diff --git a/base/android/task_scheduler/task_runner_android.cc b/base/android/task_scheduler/task_runner_android.cc index f32dc31..524bd0e 100644 --- a/base/android/task_scheduler/task_runner_android.cc +++ b/base/android/task_scheduler/task_runner_android.cc
@@ -45,4 +45,10 @@ base::android::ScopedJavaGlobalRef<jobject>(task))); } +bool TaskRunnerAndroid::BelongsToCurrentThread( + JNIEnv* env, + const base::android::JavaRef<jobject>& caller) { + return task_runner_->RunsTasksInCurrentSequence(); +} + } // namespace base
diff --git a/base/android/task_scheduler/task_runner_android.h b/base/android/task_scheduler/task_runner_android.h index 155a253..ade0dc96 100644 --- a/base/android/task_scheduler/task_runner_android.h +++ b/base/android/task_scheduler/task_runner_android.h
@@ -23,6 +23,9 @@ const base::android::JavaRef<jobject>& caller, const base::android::JavaRef<jobject>& task); + bool BelongsToCurrentThread(JNIEnv* env, + const base::android::JavaRef<jobject>& caller); + private: const scoped_refptr<TaskRunner> task_runner_;
diff --git a/base/containers/checked_iterators.h b/base/containers/checked_iterators.h index 275a693..c243ce93 100644 --- a/base/containers/checked_iterators.h +++ b/base/containers/checked_iterators.h
@@ -8,6 +8,7 @@ #include <iterator> #include <memory> +#include "base/containers/util.h" #include "base/logging.h" namespace base { @@ -129,6 +130,20 @@ return current_; } + static bool RangesOverlap(const CheckedRandomAccessIterator& from_begin, + const CheckedRandomAccessIterator& from_end, + const CheckedRandomAccessIterator& to) { + CHECK(from_begin < from_end); + const auto from_begin_uintptr = get_uintptr(from_begin.current_); + const auto from_end_uintptr = get_uintptr(from_end.current_); + const auto to_begin_uintptr = get_uintptr(to.current_); + const auto to_end_uintptr = + get_uintptr((to + std::distance(from_begin, from_end)).current_); + + return !(to_begin_uintptr >= from_end_uintptr || + to_end_uintptr <= from_begin_uintptr); + } + private: void CheckComparable(const CheckedRandomAccessIterator& other) const { CHECK_EQ(start_, other.start_); @@ -264,6 +279,20 @@ return current_; } + static bool RangesOverlap(const CheckedRandomAccessConstIterator& from_begin, + const CheckedRandomAccessConstIterator& from_end, + const CheckedRandomAccessConstIterator& to) { + CHECK(from_begin < from_end); + const auto from_begin_uintptr = get_uintptr(from_begin.current_); + const auto from_end_uintptr = get_uintptr(from_end.current_); + const auto to_begin_uintptr = get_uintptr(to.current_); + const auto to_end_uintptr = + get_uintptr((to + std::distance(from_begin, from_end)).current_); + + return !(to_begin_uintptr >= from_end_uintptr || + to_end_uintptr <= from_begin_uintptr); + } + private: void CheckComparable(const CheckedRandomAccessConstIterator& other) const { CHECK_EQ(start_, other.start_);
diff --git a/base/containers/span_unittest.cc b/base/containers/span_unittest.cc index 6a123f6b..05429a5 100644 --- a/base/containers/span_unittest.cc +++ b/base/containers/span_unittest.cc
@@ -11,6 +11,7 @@ #include <string> #include <vector> +#include "base/containers/checked_iterators.h" #include "base/macros.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -1091,4 +1092,41 @@ ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.subspan(1), ""); } +TEST(SpanTest, IteratorRangesOverlap) { + static constexpr int kArray[] = {1, 6, 1, 8, 0}; + const size_t kNumElements = 5; + constexpr span<const int> span(kArray); + + static constexpr int kOverlappingStartIndexes[] = {-4, 0, 3, 4}; + static constexpr int kNonOverlappingStartIndexes[] = {-7, -5, 5, 7}; + + // Overlapping ranges. + for (const int dest_start_index : kOverlappingStartIndexes) { + EXPECT_TRUE(CheckedRandomAccessIterator<const int>::RangesOverlap( + span.begin(), span.end(), + CheckedRandomAccessIterator<const int>( + span.data() + dest_start_index, + span.data() + dest_start_index + kNumElements))); + EXPECT_TRUE(CheckedRandomAccessConstIterator<const int>::RangesOverlap( + span.cbegin(), span.cend(), + CheckedRandomAccessConstIterator<const int>( + span.data() + dest_start_index, + span.data() + dest_start_index + kNumElements))); + } + + // Non-overlapping ranges. + for (const int dest_start_index : kNonOverlappingStartIndexes) { + EXPECT_FALSE(CheckedRandomAccessIterator<const int>::RangesOverlap( + span.begin(), span.end(), + CheckedRandomAccessIterator<const int>( + span.data() + dest_start_index, + span.data() + dest_start_index + kNumElements))); + EXPECT_FALSE(CheckedRandomAccessConstIterator<const int>::RangesOverlap( + span.cbegin(), span.cend(), + CheckedRandomAccessConstIterator<const int>( + span.data() + dest_start_index, + span.data() + dest_start_index + kNumElements))); + } +} + } // namespace base
diff --git a/base/containers/util.h b/base/containers/util.h new file mode 100644 index 0000000..a190435 --- /dev/null +++ b/base/containers/util.h
@@ -0,0 +1,19 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_CONTAINERS_UTIL_H_ +#define BASE_CONTAINERS_UTIL_H_ + +namespace base { + +// TODO(crbug.com/817982): What we really need is for checked_math.h to be +// able to do checked arithmetic on pointers. +template <typename T> +static inline uintptr_t get_uintptr(const T* t) { + return reinterpret_cast<uintptr_t>(t); +} + +} // namespace base + +#endif // BASE_CONTAINERS_UTIL_H_
diff --git a/base/containers/vector_buffer.h b/base/containers/vector_buffer.h index 2fc1796..83cd2ac 100644 --- a/base/containers/vector_buffer.h +++ b/base/containers/vector_buffer.h
@@ -11,6 +11,7 @@ #include <type_traits> #include <utility> +#include "base/containers/util.h" #include "base/logging.h" #include "base/macros.h" #include "base/numerics/checked_math.h" @@ -163,12 +164,6 @@ } private: - // TODO(crbug.com/817982): What we really need is for checked_math.h to be - // able to do checked arithmetic on pointers. - static inline uintptr_t get_uintptr(const T* t) { - return reinterpret_cast<uintptr_t>(t); - } - static bool RangesOverlap(const T* from_begin, const T* from_end, const T* to) {
diff --git a/base/debug/alias.cc b/base/debug/alias.cc index ebc8b5a4..f808c503 100644 --- a/base/debug/alias.cc +++ b/base/debug/alias.cc
@@ -8,20 +8,9 @@ namespace base { namespace debug { -#if defined(COMPILER_MSVC) -#pragma optimize("", off) -#elif defined(__clang__) -#pragma clang optimize off -#endif - -void Alias(const void* var) { -} - -#if defined(COMPILER_MSVC) -#pragma optimize("", on) -#elif defined(__clang__) -#pragma clang optimize on -#endif +// This file/function should be excluded from LTO/LTCG to ensure that the +// compiler can't see this function's implementation when compiling calls to it. +NOINLINE void Alias(const void* var) {} } // namespace debug } // namespace base
diff --git a/base/debug/stack_trace_win.cc b/base/debug/stack_trace_win.cc index a00c5885..c88e71ac7 100644 --- a/base/debug/stack_trace_win.cc +++ b/base/debug/stack_trace_win.cc
@@ -274,26 +274,13 @@ return InitializeSymbols(); } -// Disable optimizations for the StackTrace::StackTrace function. It is -// important to disable at least frame pointer optimization ("y"), since -// that breaks CaptureStackBackTrace() and prevents StackTrace from working -// in Release builds (it may still be janky if other frames are using FPO, -// but at least it will make it further). -#if defined(COMPILER_MSVC) -#pragma optimize("", off) -#endif - -StackTrace::StackTrace(size_t count) { +NOINLINE StackTrace::StackTrace(size_t count) { count = std::min(arraysize(trace_), count); // When walking our own stack, use CaptureStackBackTrace(). count_ = CaptureStackBackTrace(0, count, trace_, NULL); } -#if defined(COMPILER_MSVC) -#pragma optimize("", on) -#endif - StackTrace::StackTrace(EXCEPTION_POINTERS* exception_pointers) { InitTrace(exception_pointers->ContextRecord); }
diff --git a/base/profiler/stack_sampling_profiler.cc b/base/profiler/stack_sampling_profiler.cc index fb99cbe..abb14bd 100644 --- a/base/profiler/stack_sampling_profiler.cc +++ b/base/profiler/stack_sampling_profiler.cc
@@ -28,6 +28,11 @@ namespace base { +// Allows StackSamplingProfiler to recall a thread which should already pretty +// much be dead (thus it should be a fast Join()). +class ScopedAllowThreadRecallForStackSamplingProfiler + : public base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope {}; + namespace { // This value is used to initialize the WaitableEvent object. This MUST BE set @@ -370,7 +375,7 @@ // happen a new profiling request would have to be made within the narrow // window between StopSoon() and thread exit following the end of the 60 // second idle period. - ScopedAllowBlocking allow_blocking; + ScopedAllowThreadRecallForStackSamplingProfiler allow_thread_join; Stop(); }
diff --git a/base/test/scoped_os_info_override_win.cc b/base/test/scoped_os_info_override_win.cc index b1c4d2f..7415c13 100644 --- a/base/test/scoped_os_info_override_win.cc +++ b/base/test/scoped_os_info_override_win.cc
@@ -47,6 +47,70 @@ os_type = type == Type::kWin10Home ? PRODUCT_HOME_BASIC : PRODUCT_PROFESSIONAL; break; + case Type::kWinServer2016: + version_info.dwMajorVersion = 10; + version_info.dwMinorVersion = 0; + version_info.dwBuildNumber = 17134; + version_info.wServicePackMajor = 0; + version_info.wServicePackMinor = 0; + version_info.szCSDVersion[0] = 0; + version_info.wProductType = VER_NT_SERVER; + version_info.wSuiteMask = VER_SUITE_ENTERPRISE; + + system_info.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64; + system_info.dwNumberOfProcessors = 4; + system_info.dwAllocationGranularity = 64 * 1024; + + os_type = PRODUCT_STANDARD_SERVER; + break; + case Type::kWin81Pro: + version_info.dwMajorVersion = 6; + version_info.dwMinorVersion = 3; + version_info.dwBuildNumber = 9600; + version_info.wServicePackMajor = 0; + version_info.wServicePackMinor = 0; + version_info.szCSDVersion[0] = 0; + version_info.wProductType = VER_NT_WORKSTATION; + version_info.wSuiteMask = VER_SUITE_PERSONAL; + + system_info.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64; + system_info.dwNumberOfProcessors = 1; + system_info.dwAllocationGranularity = 64 * 1024; + + os_type = PRODUCT_PROFESSIONAL; + break; + case Type::kWinServer2012R2: + version_info.dwMajorVersion = 6; + version_info.dwMinorVersion = 3; + version_info.dwBuildNumber = 9600; + version_info.wServicePackMajor = 0; + version_info.wServicePackMinor = 0; + version_info.szCSDVersion[0] = 0; + version_info.wProductType = VER_NT_SERVER; + version_info.wSuiteMask = VER_SUITE_ENTERPRISE; + + system_info.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64; + system_info.dwNumberOfProcessors = 2; + system_info.dwAllocationGranularity = 64 * 1024; + + os_type = PRODUCT_STANDARD_SERVER; + break; + case Type::kWin7ProSP1: + version_info.dwMajorVersion = 6; + version_info.dwMinorVersion = 1; + version_info.dwBuildNumber = 7601; + version_info.wServicePackMajor = 1; + version_info.wServicePackMinor = 0; + wcscpy_s(version_info.szCSDVersion, L"Service Pack 1"); + version_info.wProductType = VER_NT_WORKSTATION; + version_info.wSuiteMask = VER_SUITE_PERSONAL; + + system_info.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64; + system_info.dwNumberOfProcessors = 1; + system_info.dwAllocationGranularity = 64 * 1024; + + os_type = PRODUCT_PROFESSIONAL; + break; } return UniqueOsInfo(new base::win::OSInfo(version_info, system_info, os_type),
diff --git a/base/test/scoped_os_info_override_win.h b/base/test/scoped_os_info_override_win.h index 256c3b3..07ae7a9 100644 --- a/base/test/scoped_os_info_override_win.h +++ b/base/test/scoped_os_info_override_win.h
@@ -28,6 +28,10 @@ enum class Type { kWin10Pro, kWin10Home, + kWinServer2016, + kWin81Pro, + kWinServer2012R2, + kWin7ProSP1, }; explicit ScopedOSInfoOverride(Type type);
diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc index 17ef722..321a555 100644 --- a/base/test/test_suite.cc +++ b/base/test/test_suite.cc
@@ -346,11 +346,12 @@ #if defined(OS_WIN) namespace { -// Disable optimizations to prevent function folding or other transformations -// that will make the call stacks on failures more confusing. -#pragma optimize("", off) // Handlers for invalid parameter, pure call, and abort. They generate a // breakpoint to ensure that we get a call stack on these failures. +// These functions should be written to be unique in order to avoid confusing +// call stacks from /OPT:ICF function folding. Printing a unique message or +// returning a unique value will do this. Note that for best results they need +// to be unique from *all* functions in Chrome. void InvalidParameter(const wchar_t* expression, const wchar_t* function, const wchar_t* file, @@ -372,7 +373,6 @@ fprintf(stderr, "\n"); __debugbreak(); } -#pragma optimize("", on) } // namespace #endif
diff --git a/base/threading/platform_thread_posix.cc b/base/threading/platform_thread_posix.cc index 7b71b9db..dff4525 100644 --- a/base/threading/platform_thread_posix.cc +++ b/base/threading/platform_thread_posix.cc
@@ -264,9 +264,8 @@ // Joining another thread may block the current thread for a long time, since // the thread referred to by |thread_handle| may still be running long-lived / // blocking tasks. - // TODO(https://crbug.com/707362): Make this a - // ScopedBlockingCallWithBaseSyncPrimitives. - base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK); + base::internal::ScopedBlockingCallWithBaseSyncPrimitives scoped_blocking_call( + base::BlockingType::MAY_BLOCK); CHECK_EQ(0, pthread_join(thread_handle.platform_handle(), nullptr)); }
diff --git a/base/threading/platform_thread_win.cc b/base/threading/platform_thread_win.cc index f6c63ac..67618d30 100644 --- a/base/threading/platform_thread_win.cc +++ b/base/threading/platform_thread_win.cc
@@ -274,9 +274,8 @@ // Record the event that this thread is blocking upon (for hang diagnosis). base::debug::ScopedThreadJoinActivity thread_activity(&thread_handle); - // TODO(https://crbug.com/707362): Make this a - // ScopedBlockingCallWithBaseSyncPrimitives. - base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK); + base::internal::ScopedBlockingCallWithBaseSyncPrimitives scoped_blocking_call( + base::BlockingType::MAY_BLOCK); // Wait for the thread to exit. It should already have terminated but make // sure this assumption is valid.
diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h index d4f6c94..33f359b 100644 --- a/base/threading/thread_restrictions.h +++ b/base/threading/thread_restrictions.h
@@ -96,8 +96,10 @@ class BrowserProcessImpl; class HistogramSynchronizer; -class NativeBackendKWallet; class KeyStorageLinux; +class NativeBackendKWallet; +class NativeDesktopMediaList; +class StartupTimeBomb; namespace android_webview { class AwFormDatabaseService; @@ -130,12 +132,14 @@ class BrowserShutdownProfileDumper; class BrowserTestBase; class CategorizedWorkerPool; +class DesktopCaptureDevice; class GpuProcessTransportFactory; class NestedMessagePumpAndroid; +class SandboxHostLinux; class ScopedAllowWaitForDebugURL; +class ServiceWorkerSubresourceLoader; class SessionStorageDatabase; class SoftwareOutputDeviceMus; -class ServiceWorkerSubresourceLoader; class SynchronousCompositor; class SynchronousCompositorHost; class SynchronousCompositorSyncCallBridge; @@ -163,6 +167,7 @@ } namespace media { class AudioInputDevice; +class AudioOutputDevice; class BlockingUrlProtocol; } namespace midi { @@ -175,6 +180,9 @@ class ScopedIPCSupport; } } +namespace printing { +class PrinterQuery; +} namespace rlz_lib { class FinancialPing; } @@ -186,7 +194,10 @@ } namespace net { class MultiThreadedCertVerifierScopedAllowBaseSyncPrimitives; +class MultiThreadedProxyResolverScopedAllowJoinOnIO; class NetworkChangeNotifierMac; +class NetworkConfigWatcherMacThread; +class ScopedAllowThreadJoinForProxyResolverV8Tracing; namespace internal { class AddressTrackerLinux; } @@ -194,6 +205,9 @@ namespace remoting { class AutoThread; +namespace protocol { +class ScopedAllowThreadJoinForWebRtcTransport; +} } namespace resource_coordinator { @@ -216,6 +230,10 @@ class HostGpuMemoryBufferManager; } +namespace vr { +class VrShell; +} + namespace webrtc { class DesktopConfigurationMonitor; } @@ -233,6 +251,7 @@ class AdjustOOMScoreHelper; class GetAppOutputScopedAllowBaseSyncPrimitives; class MessageLoopImpl; +class ScopedAllowThreadRecallForStackSamplingProfiler; class SimpleThread; class StackSamplingProfiler; class Thread; @@ -284,21 +303,20 @@ class BASE_EXPORT ScopedAllowBlocking { private: + FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, ScopedAllowBlocking); + friend class ScopedAllowBlockingForTesting; + // This can only be instantiated by friends. Use ScopedAllowBlockingForTesting // in unit tests to avoid the friend requirement. - FRIEND_TEST_ALL_PREFIXES(ThreadRestrictionsTest, ScopedAllowBlocking); friend class AdjustOOMScoreHelper; friend class android_webview::ScopedAllowInitGLBindings; - friend class audio::OutputDevice; friend class content::BrowserProcessSubThread; friend class content::GpuProcessTransportFactory; friend class cronet::CronetPrefsManager; friend class cronet::CronetURLRequestContext; - friend class media::AudioInputDevice; friend class mojo::CoreLibraryInitializer; friend class resource_coordinator::TabManagerDelegate; // crbug.com/778703 friend class ui::MaterialDesignController; - friend class ScopedAllowBlockingForTesting; friend class StackSamplingProfiler; ScopedAllowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF; @@ -391,16 +409,26 @@ // Allowed usage: friend class ::BrowserProcessImpl; // http://crbug.com/125207 friend class ::KeyStorageLinux; - friend class Thread; + friend class ::NativeDesktopMediaList; + friend class ::StartupTimeBomb; friend class android::JavaHandlerThread; + friend class audio::OutputDevice; friend class base::MessageLoopImpl; + friend class base::ScopedAllowThreadRecallForStackSamplingProfiler; friend class base::StackSamplingProfiler; + friend class base::Thread; + friend class content::DesktopCaptureDevice; + friend class content::SandboxHostLinux; friend class content::ScopedAllowWaitForDebugURL; friend class content::SynchronousCompositor; friend class content::SynchronousCompositorHost; friend class content::SynchronousCompositorSyncCallBridge; + friend class media::AudioInputDevice; + friend class media::AudioOutputDevice; friend class mojo::SyncCallRestrictions; + friend class net::NetworkConfigWatcherMacThread; friend class viz::HostGpuMemoryBufferManager; + friend class vr::VrShell; // Usage that should be fixed: friend class ::chromeos::BlockingMethodCaller; // http://crbug.com/125360 @@ -413,9 +441,16 @@ friend class disk_cache::BackendImpl; // http://crbug.com/74623 friend class disk_cache::InFlightIO; // http://crbug.com/74623 friend class gpu::GpuChannelHost; // http://crbug.com/125264 + friend class remoting::protocol:: + ScopedAllowThreadJoinForWebRtcTransport; // http://crbug.com/660081 friend class midi::TaskService; // https://crbug.com/796830 - friend class net::NetworkChangeNotifierMac; // http://crbug.com/125097 friend class net::internal::AddressTrackerLinux; // http://crbug.com/125097 + friend class net:: + MultiThreadedProxyResolverScopedAllowJoinOnIO; // http://crbug.com/69710 + friend class net::NetworkChangeNotifierMac; // http://crbug.com/125097 + friend class net:: + ScopedAllowThreadJoinForProxyResolverV8Tracing; // http://crbug.com/69710 + friend class printing::PrinterQuery; // http://crbug.com/66082 // Not used in production yet, https://crbug.com/844078. friend class service_manager::ServiceProcessLauncher; friend class ui::WindowResizeHelperMac; // http://crbug.com/902829
diff --git a/base/time/time_win_unittest.cc b/base/time/time_win_unittest.cc index 84374566..1e3001f 100644 --- a/base/time/time_win_unittest.cc +++ b/base/time/time_win_unittest.cc
@@ -66,6 +66,17 @@ return 0; } +// Measure the performance of __rdtsc so that we can compare it to the overhead +// of QueryPerformanceCounter. A hard-coded frequency is used because we don't +// care about the accuracy of the results, we just need to do the work. +// The amount of work is not exactly the same as in TimeTicks::Now (some steps +// are skipped) but that doesn't seem to materially affect the results. +TimeTicks GetTSC() { + // Using a fake QPC frequency for test purposes. + return TimeTicks() + TimeDelta::FromMicroseconds( + __rdtsc() * Time::kMicrosecondsPerSecond / 10000000); +} + } // namespace // This test spawns many threads, and can occasionally fail due to resource @@ -177,7 +188,7 @@ TEST(TimeTicks, TimerPerformance) { // Verify that various timer mechanisms can always complete quickly. // Note: This is a somewhat arbitrary test. - const int kLoops = 10000; + const int kLoops = 500000; typedef TimeTicks (*TestFunc)(); struct TestCase { @@ -191,6 +202,7 @@ std::vector<TestCase> cases; cases.push_back({reinterpret_cast<TestFunc>(&Time::Now), "Time::Now"}); cases.push_back({&TimeTicks::Now, "TimeTicks::Now"}); + cases.push_back({&GetTSC, "rdtsc"}); if (ThreadTicks::IsSupported()) { ThreadTicks::WaitUntilInitialized(); @@ -198,6 +210,16 @@ {reinterpret_cast<TestFunc>(&ThreadTicks::Now), "ThreadTicks::Now"}); } + // Warm up the CPU to its full clock rate so that we get accurate timing + // information. + DWORD start_tick = GetTickCount(); + const DWORD kWarmupMs = 50; + for (;;) { + DWORD elapsed = GetTickCount() - start_tick; + if (elapsed > kWarmupMs) + break; + } + for (const auto& test_case : cases) { TimeTicks start = TimeTicks::Now(); for (int index = 0; index < kLoops; index++)
diff --git a/base/win/process_startup_helper.cc b/base/win/process_startup_helper.cc index ffcd5cf..6861b38b 100644 --- a/base/win/process_startup_helper.cc +++ b/base/win/process_startup_helper.cc
@@ -12,9 +12,12 @@ namespace { -#pragma optimize("", off) // Handlers for invalid parameter and pure call. They generate a breakpoint to // tell breakpad that it needs to dump the process. +// These functions should be written to be unique in order to avoid confusing +// call stacks from /OPT:ICF function folding. Printing a unique message or +// returning a unique value will do this. Note that for best results they need +// to be unique from *all* functions in Chrome. void InvalidParameter(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t reserved) { @@ -28,7 +31,6 @@ // Use a different exit code from InvalidParameter to avoid COMDAT folding. _exit(2); } -#pragma optimize("", on) } // namespace
diff --git a/build/android/apk_operations.py b/build/android/apk_operations.py index 26c56e9..7e3aec1 100755 --- a/build/android/apk_operations.py +++ b/build/android/apk_operations.py
@@ -73,7 +73,7 @@ if install_dict: installer.Install(device, install_dict, apk=apk) else: - device.Install(apk, reinstall=True) + device.Install(apk, allow_downgrade=True, reinstall=True) logging.info('Installing %sincremental apk.', '' if install_dict else 'non-') device_utils.DeviceUtils.parallel(devices).pMap(install)
diff --git a/build/android/incremental_install/installer.py b/build/android/incremental_install/installer.py index a5eff693a..95475b16 100755 --- a/build/android/incremental_install/installer.py +++ b/build/android/incremental_install/installer.py
@@ -131,10 +131,16 @@ splits = [] for split_glob in split_globs: splits.extend((f for f in glob.glob(split_glob))) - device.InstallSplitApk(apk, splits, reinstall=True, - allow_cached_props=True, permissions=permissions) + device.InstallSplitApk( + apk, + splits, + allow_downgrade=True, + reinstall=True, + allow_cached_props=True, + permissions=permissions) else: - device.Install(apk, reinstall=True, permissions=permissions) + device.Install( + apk, allow_downgrade=True, reinstall=True, permissions=permissions) install_timer.Stop(log=False) # Push .so and .dex files to the device (if they have changed).
diff --git a/build/android/pylib/local/device/local_device_gtest_run.py b/build/android/pylib/local/device/local_device_gtest_run.py index 6fbff49..cafcb2e3 100644 --- a/build/android/pylib/local/device/local_device_gtest_run.py +++ b/build/android/pylib/local/device/local_device_gtest_run.py
@@ -127,8 +127,11 @@ installer.Install(device, self._test_apk_incremental_install_json, apk=self._apk_helper, permissions=self._permissions) else: - device.Install(self._apk_helper, reinstall=True, - permissions=self._permissions) + device.Install( + self._apk_helper, + allow_downgrade=True, + reinstall=True, + permissions=self._permissions) def ResultsDirectory(self, device): return device.GetApplicationDataDirectory(self._package)
diff --git a/build/chromeos/create_test_runner_script.py b/build/chromeos/create_test_runner_script.py index 3c26924a..0cbe38ba 100755 --- a/build/chromeos/create_test_runner_script.py +++ b/build/chromeos/create_test_runner_script.py
@@ -53,7 +53,7 @@ parser.add_argument('--use-vm', action='store_true') parser.add_argument('--deploy-chrome', action='store_true') parser.add_argument('--suite-name') - parser.add_argument('--tast-conditional') + parser.add_argument('--tast-attr-expr') parser.add_argument('--tast-tests', action='append') args = parser.parse_args(args) @@ -76,16 +76,16 @@ '--test-exe', args.test_exe, ]) - elif args.tast_conditional or args.tast_tests: + elif args.tast_attr_expr or args.tast_tests: vm_test_args.extend([ 'tast', '--suite-name', args.suite_name, ]) - if args.tast_conditional: + if args.tast_attr_expr: vm_test_args.extend([ - '--conditional', - args.tast_conditional, + '--attr-expr', + args.tast_attr_expr, ]) else: for t in args.tast_tests:
diff --git a/build/chromeos/test_runner.py b/build/chromeos/test_runner.py index 3052dfc..f8aa173 100755 --- a/build/chromeos/test_runner.py +++ b/build/chromeos/test_runner.py
@@ -571,9 +571,11 @@ help='Total number of external shards.') # Tast test args. + # pylint: disable=line-too-long tast_test_parser = subparsers.add_parser( 'tast', - help='Runs a vm-side set of Tast tests.') + help='Runs a vm-side set of Tast tests. For more details, see: ' + 'https://chromium.googlesource.com/chromiumos/platform/tast/+/master/docs/running_tests.md') tast_test_parser.set_defaults(func=vm_test) tast_test_parser.add_argument( '--suite-name', type=str, required=True, @@ -583,9 +585,10 @@ tast_test_parser.add_argument( '--test-launcher-summary-output', type=str, help='Generates a simple GTest-style JSON result file for the test run.') + # TODO(bpastene): Change all uses of "--conditional" to use "--attr-expr". tast_test_parser.add_argument( - '--conditional', type=str, - help='A conditional whose matching tests will run ' + '--conditional', '--attr-expr', type=str, dest='conditional', + help='A boolean expression whose matching tests will run ' '(eg: ("dep:chrome" || "dep:chrome_login")).') tast_test_parser.add_argument( '--test', '-t', action='append', dest='tests',
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 34253ae..8789e9f 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -249,7 +249,7 @@ rebase_path(_jni_generator_include, _jni_output_dir), ] - if (!is_java_debug) { + if (use_hashed_jni_names) { args += [ "--use_proxy_hash" ] }
diff --git a/build/config/chromeos/rules.gni b/build/config/chromeos/rules.gni index 2b93ddd..bcba20c 100644 --- a/build/config/chromeos/rules.gni +++ b/build/config/chromeos/rules.gni
@@ -31,7 +31,7 @@ # Args: # test_exe: Name of test binary located in the out dir. This will get copied # to the VM and executed there. -# tast_conditional: Tast conditional to pass to local_test_runner on the VM. +# tast_attr_expr: Tast expression to pass to local_test_runner on the VM. # tast_tests: List of Tast tests to run on the VM. Note that when this is # specified, the target name used to invoke this template will be # designated as the "name" of this test and will primarly used for test @@ -47,7 +47,7 @@ "deploy_chrome", "generated_script", "runtime_deps_file", - "tast_conditional", + "tast_attr_expr", "tast_tests", "testonly", "test_exe", @@ -65,7 +65,7 @@ assert(defined(generated_script), "Must specify where to place generated test launcher script via " + "'generated_script'") - is_tast = defined(tast_conditional) || defined(tast_tests) + is_tast = defined(tast_attr_expr) || defined(tast_tests) assert(!(is_tast && defined(test_exe)), "Tast tests are invoked from binaries shipped with the VM image. " + "There should be no locally built binary needed.") @@ -176,10 +176,10 @@ "--suite-name", target_name, ] - if (defined(tast_conditional)) { + if (defined(tast_attr_expr)) { args += [ - "--tast-conditional", - tast_conditional, + "--tast-attr-expr", + tast_attr_expr, ] } else { foreach(test, tast_tests) { @@ -194,16 +194,28 @@ } template("tast_test") { - assert(defined(invoker.tast_conditional) != defined(invoker.tast_tests), - "Specify one of tast_tests or tast_conditional.") + forward_variables_from(invoker, "*") + # Default the expression to match any chrome-related test. + if (!defined(tast_attr_expr) && !defined(tast_tests)) { + tast_attr_expr = "!disabled && !\"group:*\" && !informational" + + " && (\"dep:chrome\" || \"dep:chrome_login\")" + } else { + assert(defined(tast_attr_expr) != defined(tast_tests), + "Specify one of tast_tests or tast_attr_expr.") + } + + # Append any disabled tests to the expression. + if (defined(tast_disabled_tests)) { + assert(defined(tast_attr_expr), + "tast_attr_expr must be used when specifying tast_disabled_tests.") + foreach(test, tast_disabled_tests) { + tast_attr_expr += " && !\"name:${test}\"" + } + tast_attr_expr = "( " + tast_attr_expr + " )" + } generate_runner_script(target_name) { testonly = true - if (defined(invoker.tast_conditional)) { - tast_conditional = invoker.tast_conditional - } else if (defined(invoker.tast_tests)) { - tast_tests = invoker.tast_tests - } generated_script = "$root_build_dir/bin/run_${target_name}" runtime_deps_file = "$root_out_dir/${target_name}.runtime_deps" deploy_chrome = true
diff --git a/build/config/fuchsia/testing_sandbox_policy b/build/config/fuchsia/testing_sandbox_policy index d295d05..bbd41f3 100644 --- a/build/config/fuchsia/testing_sandbox_policy +++ b/build/config/fuchsia/testing_sandbox_policy
@@ -3,6 +3,7 @@ "vulkan" ], "dev": ["null", "zero"], "services": [ + "chromium.web.ContextProvider", "fuchsia.fonts.Provider", "fuchsia.media.Audio", "fuchsia.mediacodec.CodecFactory",
diff --git a/build/config/posix/BUILD.gn b/build/config/posix/BUILD.gn index 97113b9..af09c96 100644 --- a/build/config/posix/BUILD.gn +++ b/build/config/posix/BUILD.gn
@@ -2,13 +2,13 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//buildtools/deps_revisions.gni") import("//build/config/c++/c++.gni") import("//build/config/clang/clang.gni") import("//build/config/compiler/compiler.gni") import("//build/config/sanitizers/sanitizers.gni") import("//build/config/sysroot.gni") import("//build/toolchain/toolchain.gni") +import("//buildtools/deps_revisions.gni") # TODO(crbug.com/830987): Come up with a better name for is POSIX + Fuchsia # configuration. @@ -50,6 +50,7 @@ defines += [ "CR_LIBCXX_REVISION=$libcxx_svn_revision", "CR_LIBCXXABI_REVISION=$libcxxabi_svn_revision", + "_LIBCPP_ABI_UNSTABLE", "_LIBCPP_ENABLE_NODISCARD", ]
diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn index f27f192e..9e6ead0 100644 --- a/build/config/win/BUILD.gn +++ b/build/config/win/BUILD.gn
@@ -2,9 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//buildtools/deps_revisions.gni") -import("//build/config/chrome_build.gni") import("//build/config/c++/c++.gni") +import("//build/config/chrome_build.gni") import("//build/config/clang/clang.gni") import("//build/config/compiler/compiler.gni") import("//build/config/sanitizers/sanitizers.gni") @@ -12,6 +11,7 @@ import("//build/timestamp.gni") import("//build/toolchain/goma.gni") import("//build/toolchain/toolchain.gni") +import("//buildtools/deps_revisions.gni") assert(is_win) @@ -270,6 +270,7 @@ defines += [ "CR_LIBCXX_REVISION=$libcxx_svn_revision", "CR_LIBCXXABI_REVISION=$libcxxabi_svn_revision", + "_LIBCPP_ABI_UNSTABLE", "_LIBCPP_ENABLE_NODISCARD", # Prevent libc++ from embedding linker flags to try to automatically link
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index e08275d..f0e59dd 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -4b11ec4b112443c09d942261fcc7c33fdad99046 \ No newline at end of file +b60658d124143c596deb72b12f57cd9416ac6f42 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index e3f3159..78d25fd 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -24a01f26ee4236e84d0b573527e9f36e00b2fc34 \ No newline at end of file +e76e2612e0a32bbd00fc38cd7d3d0de71cab08c1 \ No newline at end of file
diff --git a/build/fuchsia/run_package.py b/build/fuchsia/run_package.py index bf25775..c0f8ccd 100644 --- a/build/fuchsia/run_package.py +++ b/build/fuchsia/run_package.py
@@ -114,7 +114,7 @@ # Register the repo. return_code = target.RunCommand( - ['amber_ctl', 'add_src', '-f', + ['amber_ctl', 'add_src', '-x', '-f', 'http://127.0.0.1:%d/repo_config.json' % remote_port]) if return_code != 0: raise Exception('Error code %d when running amber_ctl.' % return_code)
diff --git a/build/util/lastchange.py b/build/util/lastchange.py index 82c5f394..fd55ce3 100755 --- a/build/util/lastchange.py +++ b/build/util/lastchange.py
@@ -9,7 +9,7 @@ import re import logging -import optparse +import argparse import os import subprocess import sys @@ -155,62 +155,62 @@ if argv is None: argv = sys.argv - parser = optparse.OptionParser(usage="lastchange.py [options]") - parser.add_option("-m", "--version-macro", + parser = argparse.ArgumentParser(usage="lastchange.py [options]") + parser.add_argument("-m", "--version-macro", help="Name of C #define when using --header. Defaults to " + "LAST_CHANGE.", default="LAST_CHANGE") - parser.add_option("-o", "--output", metavar="FILE", + parser.add_argument("-o", "--output", metavar="FILE", help="Write last change to FILE. " + "Can be combined with --header to write both files.") - parser.add_option("", "--header", metavar="FILE", - help="Write last change to FILE as a C/C++ header. " + - "Can be combined with --output to write both files.") - parser.add_option("--revision-id-only", action='store_true', - help="Output the revision as a VCS revision ID only (in " + - "Git, a 40-character commit hash, excluding the " + - "Cr-Commit-Position).") - parser.add_option("--print-only", action='store_true', - help="Just print the revision string. Overrides any " + - "file-output-related options.") - parser.add_option("-s", "--source-dir", metavar="DIR", + parser.add_argument("--header", metavar="FILE", + help=("Write last change to FILE as a C/C++ header. " + "Can be combined with --output to write both files.")) + parser.add_argument("--revision-id-only", action='store_true', + help=("Output the revision as a VCS revision ID only (in " + "Git, a 40-character commit hash, excluding the " + "Cr-Commit-Position).")) + parser.add_argument("--print-only", action='store_true', + help=("Just print the revision string. Overrides any " + "file-output-related options.")) + parser.add_argument("-s", "--source-dir", metavar="DIR", help="Use repository in the given directory.") - parser.add_option("", "--filter", metavar="REGEX", - help="Only use log entries where the commit message " + - "matches the supplied filter regex. Defaults to " + - "'^Change-Id:' to suppress local commits.", + parser.add_argument("--filter", metavar="REGEX", + help=("Only use log entries where the commit message " + "matches the supplied filter regex. Defaults to " + "'^Change-Id:' to suppress local commits."), default='^Change-Id:') - opts, args = parser.parse_args(argv[1:]) + args, extras = parser.parse_known_args(argv[1:]) logging.basicConfig(level=logging.WARNING) - out_file = opts.output - header = opts.header - filter=opts.filter + out_file = args.output + header = args.header + filter=args.filter - while len(args) and out_file is None: + while len(extras) and out_file is None: if out_file is None: - out_file = args.pop(0) - if args: - sys.stderr.write('Unexpected arguments: %r\n\n' % args) + out_file = extras.pop(0) + if extras: + sys.stderr.write('Unexpected arguments: %r\n\n' % extras) parser.print_help() sys.exit(2) - if opts.source_dir: - src_dir = opts.source_dir + if args.source_dir: + src_dir = args.source_dir else: src_dir = os.path.dirname(os.path.abspath(__file__)) version_info = FetchVersionInfo(directory=src_dir, filter=filter) revision_string = version_info.revision - if opts.revision_id_only: + if args.revision_id_only: revision_string = version_info.revision_id - if opts.print_only: + if args.print_only: print revision_string else: contents = "LASTCHANGE=%s\n" % revision_string - if not out_file and not opts.header: + if not out_file and not args.header: sys.stdout.write(contents) else: if out_file: @@ -221,7 +221,7 @@ timefile.write(str(version_info.timestamp)) if header: WriteIfChanged(header, - GetHeaderContents(header, opts.version_macro, + GetHeaderContents(header, args.version_macro, revision_string)) return 0
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index 8a259d0..10f3a63 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc
@@ -967,6 +967,28 @@ SetNeedsCommit(); } +bool Layer::GetUserScrollableHorizontal() const { + // When using layer lists, horizontal scrollability is stored in scroll nodes. + if (layer_tree_host() && layer_tree_host()->IsUsingLayerLists()) { + auto& scroll_tree = layer_tree_host()->property_trees()->scroll_tree; + if (auto* scroll_node = scroll_tree.Node(scroll_tree_index_)) + return scroll_node->user_scrollable_horizontal; + return false; + } + return inputs_.user_scrollable_horizontal; +} + +bool Layer::GetUserScrollableVertical() const { + // When using layer lists, vertical scrollability is stored in scroll nodes. + if (layer_tree_host() && layer_tree_host()->IsUsingLayerLists()) { + auto& scroll_tree = layer_tree_host()->property_trees()->scroll_tree; + if (auto* scroll_node = scroll_tree.Node(scroll_tree_index_)) + return scroll_node->user_scrollable_vertical; + return false; + } + return inputs_.user_scrollable_vertical; +} + uint32_t Layer::GetMainThreadScrollingReasons() const { // When using layer lists, main thread scrolling reasons are stored in scroll // nodes.
diff --git a/cc/layers/layer.h b/cc/layers/layer.h index 4edf0e18..370b2da 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h
@@ -404,7 +404,7 @@ bool is_scrollbar() const { return inputs_.is_scrollbar; } // Set or get if this layer is able to be scrolled along each axis. These are - // independant of the scrollable state, or size of the scrollable area + // independent of the scrollable state, or size of the scrollable area // specified in SetScrollable(), as these may be enabled or disabled // dynamically, while SetScrollable() defines what would be possible if these // are enabled. @@ -413,12 +413,8 @@ // the scrollbars will be shown when the scroll offset changes if these are // set to true. void SetUserScrollable(bool horizontal, bool vertical); - bool user_scrollable_horizontal() const { - return inputs_.user_scrollable_horizontal; - } - bool user_scrollable_vertical() const { - return inputs_.user_scrollable_vertical; - } + bool GetUserScrollableHorizontal() const; + bool GetUserScrollableVertical() const; // Set or get if this layer is able to be scrolled on the compositor thread. // This only applies for layers that are marked as scrollable, not for layers
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc index 06c01600..8cad55f 100644 --- a/cc/trees/property_tree_builder.cc +++ b/cc/trees/property_tree_builder.cc
@@ -1070,7 +1070,7 @@ } static inline bool UserScrollableHorizontal(Layer* layer) { - return layer->user_scrollable_horizontal(); + return layer->GetUserScrollableHorizontal(); } static inline bool UserScrollableHorizontal(LayerImpl* layer) { @@ -1078,7 +1078,7 @@ } static inline bool UserScrollableVertical(Layer* layer) { - return layer->user_scrollable_vertical(); + return layer->GetUserScrollableVertical(); } static inline bool UserScrollableVertical(LayerImpl* layer) {
diff --git a/chrome/VERSION b/chrome/VERSION index 8fbf5c0..ceab39d 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=73 MINOR=0 -BUILD=3646 +BUILD=3647 PATCH=0
diff --git a/chrome/android/java/res/layout/keyboard_accessory.xml b/chrome/android/java/res/layout/keyboard_accessory.xml index a572088..6ceba46 100644 --- a/chrome/android/java/res/layout/keyboard_accessory.xml +++ b/chrome/android/java/res/layout/keyboard_accessory.xml
@@ -36,11 +36,7 @@ android:orientation="horizontal" android:background="@color/modern_grey_100"> - <android.support.design.widget.TabLayout - android:id="@+id/tabs" - app:tabIndicatorHeight="0dp" - android:layout_width="wrap_content" - android:layout_height="match_parent"/> + <include layout="@layout/keyboard_accessory_tabs"/> <View style="@style/VerticalDivider" />
diff --git a/chrome/android/java/res/layout/keyboard_accessory_modern.xml b/chrome/android/java/res/layout/keyboard_accessory_modern.xml index 5750654f..a19c6be 100644 --- a/chrome/android/java/res/layout/keyboard_accessory_modern.xml +++ b/chrome/android/java/res/layout/keyboard_accessory_modern.xml
@@ -69,13 +69,7 @@ android:layout_weight="0" style="@style/VerticalDivider" /> - <android.support.design.widget.TabLayout - android:id="@+id/tabs" - app:tabIndicatorHeight="0dp" - android:layout_gravity="end" - android:layout_width="wrap_content" - android:layout_weight="0" - android:layout_height="match_parent"/> + <include layout="@layout/keyboard_accessory_tabs" /> </LinearLayout> </org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryModernView>
diff --git a/chrome/android/java/res/layout/keyboard_accessory_tabs.xml b/chrome/android/java/res/layout/keyboard_accessory_tabs.xml index b88a339..21e37655 100644 --- a/chrome/android/java/res/layout/keyboard_accessory_tabs.xml +++ b/chrome/android/java/res/layout/keyboard_accessory_tabs.xml
@@ -3,11 +3,13 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<android.support.design.widget.TabLayout +<org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryTabLayoutView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/tabs" app:tabIndicatorHeight="0dp" + app:tabTextColor="@color/default_icon_color" + app:tabSelectedTextColor="@color/default_icon_color_blue" android:layout_gravity="end" android:layout_width="wrap_content" android:layout_weight="0"
diff --git a/chrome/android/java/res_autofill_assistant/drawable/autofill_assistant_checkbox_bg.xml b/chrome/android/java/res_autofill_assistant/drawable/autofill_assistant_checkbox_bg.xml deleted file mode 100644 index 08605a2..0000000 --- a/chrome/android/java/res_autofill_assistant/drawable/autofill_assistant_checkbox_bg.xml +++ /dev/null
@@ -1,11 +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. --> -<shape - xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle"> - <corners - android:radius="4dp" /> - <solid - android:color="@color/autofill_assistant_light_blue" /> -</shape>
diff --git a/chrome/android/java/res_autofill_assistant/layout/init_screen.xml b/chrome/android/java/res_autofill_assistant/layout/init_screen.xml index 8624b6c..01944d5 100644 --- a/chrome/android/java/res_autofill_assistant/layout/init_screen.xml +++ b/chrome/android/java/res_autofill_assistant/layout/init_screen.xml
@@ -70,30 +70,44 @@ android:layout_height="wrap_content" android:layout_width="wrap_content" android:textAppearance="@style/BlackTitle2" + android:gravity="center_horizontal" android:text="@string/autofill_assistant_onboarding_title" /> <!-- Subtitle (e.g., 'Google Assistant saves you time...')--> - <Space android:layout_width="0dp" android:layout_height="10dp"/> + <Space android:layout_width="0dp" android:layout_height="16dp"/> <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" - android:textAppearance="@style/BlackBodyDefault" + android:textAppearance="@style/BlackBody" android:paddingStart="35dp" android:paddingEnd="35dp" + android:gravity="center_horizontal" android:text="@string/autofill_assistant_init_message" /> + <!-- Separator --> + <Space android:layout_width="0dp" android:layout_height="24dp"/> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_horizontal" + android:orientation="horizontal" + android:weightSum="1.0"> + <View style="@style/HorizontalDivider" + android:layout_width="0dp" + android:layout_height="2dp" + android:layout_weight="0.33"/> + </LinearLayout> + <Space android:layout_width="0dp" android:layout_height="24dp"/> + <!-- Terms and Conditions message and link --> - <Space android:layout_width="0dp" android:layout_height="25dp"/> <LinearLayout android:layout_height="wrap_content" android:layout_width="match_parent" android:paddingStart="12dp" android:paddingEnd="12dp" - android:paddingTop="9dp" android:paddingBottom="9dp" android:layout_marginStart="16dp" - android:layout_marginEnd="16dp" - android:background="@drawable/autofill_assistant_checkbox_bg" > + android:layout_marginEnd="16dp"> <TextView android:id="@+id/google_terms_message" @@ -101,7 +115,7 @@ android:layout_height="wrap_content" android:layout_margin="0dp" android:layout_gravity="center" - android:textAppearance="@style/BlackBodyDefault" + android:textAppearance="@style/BlackCaption" android:text="@string/autofill_assistant_google_terms_description" /> </LinearLayout> @@ -128,7 +142,7 @@ android:paddingEnd="24dp" android:paddingTop="9dp" android:paddingBottom="9dp" - android:text="@string/no_thanks" + android:text="@string/cancel" style="@style/TextButton" /> <Space
diff --git a/chrome/android/java/res_autofill_assistant/values-v17/colors.xml b/chrome/android/java/res_autofill_assistant/values-v17/colors.xml index 65c63e2e..2cff0ce 100644 --- a/chrome/android/java/res_autofill_assistant/values-v17/colors.xml +++ b/chrome/android/java/res_autofill_assistant/values-v17/colors.xml
@@ -9,6 +9,5 @@ Please see src/ui/android/java/res/values/colors.xml for the shared common colors. --> - <color name="autofill_assistant_light_blue">#e9f0fd</color> <color name="autofill_assistant_light_grey">@color/modern_grey_300</color> </resources>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetCoordinator.java index 301a8a6..8b2ee78 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetCoordinator.java
@@ -7,6 +7,7 @@ import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.ACTIVE_TAB_INDEX; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.HEIGHT; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.NO_ACTIVE_TAB; +import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.PAGE_CHANGE_LISTENER; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.TABS; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.TOP_SHADOW_VISIBLE; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.VISIBLE; @@ -39,14 +40,14 @@ * @param viewProvider A provider for the accessory layout. */ public AccessorySheetCoordinator(ViewProvider<AccessorySheetView> viewProvider) { - PropertyModel model = - new PropertyModel - .Builder(TABS, ACTIVE_TAB_INDEX, VISIBLE, HEIGHT, TOP_SHADOW_VISIBLE) - .with(TABS, new ListModel<>()) - .with(ACTIVE_TAB_INDEX, NO_ACTIVE_TAB) - .with(VISIBLE, false) - .with(TOP_SHADOW_VISIBLE, false) - .build(); + PropertyModel model = new PropertyModel + .Builder(TABS, ACTIVE_TAB_INDEX, VISIBLE, HEIGHT, + TOP_SHADOW_VISIBLE, PAGE_CHANGE_LISTENER) + .with(TABS, new ListModel<>()) + .with(ACTIVE_TAB_INDEX, NO_ACTIVE_TAB) + .with(VISIBLE, false) + .with(TOP_SHADOW_VISIBLE, false) + .build(); LazyConstructionPropertyMcp.create( model, VISIBLE, viewProvider, AccessorySheetViewBinder::bind); @@ -149,4 +150,8 @@ public void setActiveTab(int position) { mMediator.setActiveTab(position); } + + void setOnPageChangeListener(ViewPager.OnPageChangeListener onPageChangeListener) { + mMediator.setOnPageChangeListener(onPageChangeListener); + } } \ No newline at end of file
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 ce723f9..c30da75 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
@@ -6,12 +6,14 @@ import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.ACTIVE_TAB_INDEX; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.NO_ACTIVE_TAB; +import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.PAGE_CHANGE_LISTENER; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.TABS; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.TOP_SHADOW_VISIBLE; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.VISIBLE; import android.support.annotation.Nullable; import android.support.annotation.Px; +import android.support.v4.view.ViewPager; import android.support.v7.widget.RecyclerView; import org.chromium.base.VisibleForTesting; @@ -133,9 +135,13 @@ return; } if (propertyKey == ACTIVE_TAB_INDEX || propertyKey == AccessorySheetProperties.HEIGHT - || propertyKey == TOP_SHADOW_VISIBLE) { + || propertyKey == TOP_SHADOW_VISIBLE || propertyKey == PAGE_CHANGE_LISTENER) { return; } assert false : "Every property update needs to be handled explicitly!"; } + + void setOnPageChangeListener(ViewPager.OnPageChangeListener onPageChangeListener) { + mModel.set(PAGE_CHANGE_LISTENER, onPageChangeListener); + } } \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetProperties.java index c429c24..5639a37 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetProperties.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetProperties.java
@@ -4,11 +4,14 @@ package org.chromium.chrome.browser.autofill.keyboard_accessory; +import android.support.v4.view.ViewPager; + import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData.Tab; import org.chromium.chrome.browser.modelutil.ListModel; import org.chromium.chrome.browser.modelutil.PropertyModel.ReadableObjectPropertyKey; import org.chromium.chrome.browser.modelutil.PropertyModel.WritableBooleanPropertyKey; import org.chromium.chrome.browser.modelutil.PropertyModel.WritableIntPropertyKey; +import org.chromium.chrome.browser.modelutil.PropertyModel.WritableObjectPropertyKey; /** * This model holds all view state of the accessory sheet. @@ -23,6 +26,8 @@ public static final WritableIntPropertyKey HEIGHT = new WritableIntPropertyKey(); public static final WritableBooleanPropertyKey TOP_SHADOW_VISIBLE = new WritableBooleanPropertyKey(); + public static final WritableObjectPropertyKey<ViewPager.OnPageChangeListener> + PAGE_CHANGE_LISTENER = new WritableObjectPropertyKey<>(); public static final int NO_ACTIVE_TAB = -1;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetViewBinder.java index 95372e5..36634a5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetViewBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetViewBinder.java
@@ -7,6 +7,7 @@ import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.ACTIVE_TAB_INDEX; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.HEIGHT; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.NO_ACTIVE_TAB; +import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.PAGE_CHANGE_LISTENER; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.TABS; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.TOP_SHADOW_VISIBLE; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetProperties.VISIBLE; @@ -44,6 +45,10 @@ if (model.get(ACTIVE_TAB_INDEX) != NO_ACTIVE_TAB) { view.setCurrentItem(model.get(ACTIVE_TAB_INDEX)); } + } else if (propertyKey == PAGE_CHANGE_LISTENER) { + if (model.get(PAGE_CHANGE_LISTENER) != null) { + view.addOnPageChangeListener(model.get(PAGE_CHANGE_LISTENER)); + } } else { assert false : "Every possible property update needs to be handled!"; }
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 d8bf7c4..02335fc 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
@@ -5,23 +5,21 @@ package org.chromium.chrome.browser.autofill.keyboard_accessory; import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.ACTIONS; -import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.ACTIVE_TAB; import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.BOTTOM_OFFSET_PX; +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.KEYBOARD_TOGGLE_VISIBLE; import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.SHOW_KEYBOARD_CALLBACK; -import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.TABS; -import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.TAB_SELECTION_CALLBACKS; import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.VISIBLE; +import android.support.annotation.Nullable; import android.support.annotation.Px; +import android.support.v4.view.ViewPager; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryModernViewBinder.ModernActionViewHolder; 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.LazyConstructionPropertyMcp; import org.chromium.chrome.browser.modelutil.ListModel; -import org.chromium.chrome.browser.modelutil.ListModelChangeProcessor; import org.chromium.chrome.browser.modelutil.PropertyKey; import org.chromium.chrome.browser.modelutil.PropertyModel; import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor; @@ -36,6 +34,8 @@ */ public class KeyboardAccessoryCoordinator { private final KeyboardAccessoryMediator mMediator; + private final KeyboardAccessoryTabLayoutCoordinator mTabLayout = + new KeyboardAccessoryTabLayoutCoordinator(); /** * The keyboard accessory provides signals when to show or change the accessory sheet below it. @@ -67,6 +67,50 @@ } /** + * Describes a delegate manages all known tabs and is responsible to determine the active tab. + */ + public interface TabSwitchingDelegate { + /** + * A {@link KeyboardAccessoryData.Tab} passed into this function will be represented as item + * at the start of the tab layout. It is meant to trigger various bottom sheets. + * @param tab The tab which contains representation data of a bottom sheet. + */ + void addTab(KeyboardAccessoryData.Tab tab); + + /** + * The {@link KeyboardAccessoryData.Tab} passed into this function will be completely + * removed from the tab layout. + * @param tab The tab to be removed. + */ + void removeTab(KeyboardAccessoryData.Tab tab); + + /** + * Clears all currently known tabs and adds the given tabs as replacement. + * @param tabs An array of {@link KeyboardAccessoryData.Tab}s. + */ + void setTabs(KeyboardAccessoryData.Tab[] tabs); + + /** + * Closes any active tab so that {@link #getActiveTab} returns null again. + */ + void closeActiveTab(); + + /** + * Returns whether active tab or null if no tab is currently active. The returned property + * reflects the latest change while the view might still be in progress of being updated. + * @return The active {@link KeyboardAccessoryData.Tab}, null otherwise. + */ + @Nullable + KeyboardAccessoryData.Tab getActiveTab(); + + /** + * Returns whether the model holds any tabs. + * @return True if there is at least one tab, false otherwise. + */ + boolean hasTabs(); + } + + /** * Initializes the component as soon as the native library is loaded by e.g. starting to listen * to keyboard visibility events. * @param viewProvider A provider for the accessory. @@ -74,16 +118,17 @@ public KeyboardAccessoryCoordinator(VisibilityDelegate visibilityDelegate, ViewProvider<KeyboardAccessoryView> viewProvider) { PropertyModel model = new PropertyModel - .Builder(ACTIONS, TABS, VISIBLE, BOTTOM_OFFSET_PX, ACTIVE_TAB, - TAB_SELECTION_CALLBACKS, SHOW_KEYBOARD_CALLBACK) - .with(TABS, new ListModel<>()) + .Builder(ACTIONS, VISIBLE, BOTTOM_OFFSET_PX, + KEYBOARD_TOGGLE_VISIBLE, SHOW_KEYBOARD_CALLBACK) .with(ACTIONS, new ListModel<>()) - .with(ACTIVE_TAB, null) .with(VISIBLE, false) + .with(KEYBOARD_TOGGLE_VISIBLE, false) .build(); - mMediator = new KeyboardAccessoryMediator(model, visibilityDelegate); - viewProvider.whenLoaded(view -> view.setTabSelectionAdapter(mMediator)); + mMediator = new KeyboardAccessoryMediator( + model, visibilityDelegate, mTabLayout.getTabSwitchingDelegate()); + viewProvider.whenLoaded(barView -> mTabLayout.assignNewView(barView.getTabLayout())); + mTabLayout.setTabObserver(mMediator); PropertyModelChangeProcessor .ViewBinder<PropertyModel, KeyboardAccessoryView, PropertyKey> viewBinder = KeyboardAccessoryViewBinder::bind; @@ -91,7 +136,8 @@ viewBinder = KeyboardAccessoryModernViewBinder::bind; } LazyConstructionPropertyMcp.create(model, VISIBLE, viewProvider, viewBinder); - KeyboardAccessoryMetricsRecorder.registerKeyboardAccessoryModelMetricsObserver(model); + KeyboardAccessoryMetricsRecorder.registerKeyboardAccessoryModelMetricsObserver( + model, mTabLayout.getTabSwitchingDelegate()); } /** @@ -112,23 +158,8 @@ factory); } - /** - * Creates the {@link TabViewBinder} that is linked to the {@link ListModelChangeProcessor} that - * connects the given {@link KeyboardAccessoryView} to the given action list. - * @param model the {@link KeyboardAccessoryProperties} whose data is used by the TabViewBinder. - * @param inflatedView the {@link KeyboardAccessoryView} to which the TabViewBinder binds data. - * @return Returns a fully initialized and wired {@link TabViewBinder}. - */ - static TabViewBinder createTabViewBinder( - PropertyModel model, KeyboardAccessoryView inflatedView) { - TabViewBinder tabViewBinder = new TabViewBinder(); - model.get(TABS).addObserver( - new ListModelChangeProcessor<>(model.get(TABS), inflatedView, tabViewBinder)); - return tabViewBinder; - } - public void closeActiveTab() { - mMediator.closeActiveTab(); + mTabLayout.getTabSwitchingDelegate().closeActiveTab(); } /** @@ -137,7 +168,7 @@ * @param tab The tab which contains representation data and links back to a bottom sheet. */ void addTab(KeyboardAccessoryData.Tab tab) { - mMediator.addTab(tab); + mTabLayout.getTabSwitchingDelegate().addTab(tab); } /** @@ -146,11 +177,11 @@ * @param tab The tab to be removed. */ void removeTab(KeyboardAccessoryData.Tab tab) { - mMediator.removeTab(tab); + mTabLayout.getTabSwitchingDelegate().removeTab(tab); } void setTabs(KeyboardAccessoryData.Tab[] tabs) { - mMediator.setTabs(tabs); + mTabLayout.getTabSwitchingDelegate().setTabs(tabs); } /** @@ -220,14 +251,23 @@ /** * Returns whether the active tab is non-null. The returned property reflects the latest change * while the view might still be in progress of being updated accordingly. - * @return True if the accessory has an active tab, false otherwise. + * @return True if the accessory is visible and has an active tab, false otherwise. */ public boolean hasActiveTab() { return mMediator.hasActiveTab(); } + ViewPager.OnPageChangeListener getOnPageChangeListener() { + return mTabLayout.getStablePageChangeListener(); + } + @VisibleForTesting KeyboardAccessoryMediator getMediatorForTesting() { return mMediator; } + + @VisibleForTesting + KeyboardAccessoryTabLayoutCoordinator getTabLayoutForTesting() { + return mTabLayout; + } }
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 9c3991d..7caab6aa0 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
@@ -6,18 +6,16 @@ import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetTrigger.MANUAL_CLOSE; import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.ACTIONS; -import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.ACTIVE_TAB; import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.BOTTOM_OFFSET_PX; +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.KEYBOARD_TOGGLE_VISIBLE; import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.SHOW_KEYBOARD_CALLBACK; -import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.TABS; -import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.TAB_SELECTION_CALLBACKS; import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.VISIBLE; import android.support.annotation.Nullable; import android.support.annotation.Px; -import android.support.design.widget.TabLayout; import org.chromium.base.VisibleForTesting; +import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryCoordinator.TabSwitchingDelegate; import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryCoordinator.VisibilityDelegate; import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData.Action; import org.chromium.chrome.browser.modelutil.ListObservable; @@ -40,22 +38,23 @@ implements ListObservable.ListObserver<Void>, PropertyObservable.PropertyObserver<PropertyKey>, KeyboardAccessoryData.Observer<KeyboardAccessoryData.Action[]>, - TabLayout.OnTabSelectedListener { + KeyboardAccessoryTabLayoutCoordinator.AccessoryTabObserver { private final PropertyModel mModel; private final VisibilityDelegate mVisibilityDelegate; + private final TabSwitchingDelegate mTabSwitcher; private boolean mShowIfNotEmpty; - KeyboardAccessoryMediator(PropertyModel model, VisibilityDelegate visibilityDelegate) { + KeyboardAccessoryMediator(PropertyModel model, VisibilityDelegate visibilityDelegate, + TabSwitchingDelegate tabSwitcher) { mModel = model; mVisibilityDelegate = visibilityDelegate; + mTabSwitcher = tabSwitcher; // Add mediator as observer so it can use model changes as signal for accessory visibility. - mModel.addObserver(this); - mModel.get(TABS).addObserver(this); - mModel.get(ACTIONS).addObserver(this); - mModel.set(TAB_SELECTION_CALLBACKS, this); mModel.set(SHOW_KEYBOARD_CALLBACK, this::closeSheet); + mModel.get(ACTIONS).addObserver(this); + mModel.addObserver(this); } @Override @@ -68,7 +67,7 @@ if (a.getActionType() == typeId) continue; retainedActions.add(a); } - // Always append autofill suggestions to the very end. + // Append autofill suggestions to the end, right before the tab switcher. int insertPos = typeId == AccessoryAction.AUTOFILL_SUGGESTION ? retainedActions.size() : 0; retainedActions.addAll(insertPos, Arrays.asList(actions)); mModel.get(ACTIONS).set(retainedActions); @@ -84,27 +83,11 @@ updateVisibility(); } - void addTab(KeyboardAccessoryData.Tab tab) { - mModel.get(TABS).add(tab); - } - - void removeTab(KeyboardAccessoryData.Tab tab) { - mModel.get(TABS).remove(tab); - } - - void setTabs(KeyboardAccessoryData.Tab[] tabs) { - mModel.get(TABS).set(tabs); - } - void dismiss() { - closeActiveTab(); + mTabSwitcher.closeActiveTab(); close(); } - void closeActiveTab() { - mModel.set(ACTIVE_TAB, null); - } - @VisibleForTesting PropertyModel getModelForTesting() { return mModel; @@ -112,20 +95,20 @@ @Override public void onItemRangeInserted(ListObservable source, int index, int count) { - assert source == mModel.get(ACTIONS) || source == mModel.get(TABS); + assert source == mModel.get(ACTIONS); updateVisibility(); } @Override public void onItemRangeRemoved(ListObservable source, int index, int count) { - assert source == mModel.get(ACTIONS) || source == mModel.get(TABS); + assert source == mModel.get(ACTIONS); updateVisibility(); } @Override public void onItemRangeChanged( ListObservable source, int index, int count, @Nullable Void payload) { - assert source == mModel.get(ACTIONS) || source == mModel.get(TABS); + assert source == mModel.get(ACTIONS); assert payload == null; updateVisibility(); } @@ -136,7 +119,7 @@ // Update the visibility only if we haven't set it just now. if (propertyKey == VISIBLE) { // When the accessory just (dis)appeared, there should be no active tab. - closeActiveTab(); + mTabSwitcher.closeActiveTab(); mVisibilityDelegate.onBottomControlSpaceChanged(); if (!mModel.get(VISIBLE)) { // TODO(fhorschig|ioanap): Maybe the generation bridge should take care of that. @@ -144,52 +127,48 @@ } return; } - if (propertyKey == ACTIVE_TAB) { - Integer activeTab = mModel.get(ACTIVE_TAB); - if (activeTab == null) { - mVisibilityDelegate.onCloseAccessorySheet(); - updateVisibility(); - return; - } - mVisibilityDelegate.onChangeAccessorySheet(activeTab); - return; - } - if (propertyKey == BOTTOM_OFFSET_PX || propertyKey == TAB_SELECTION_CALLBACKS - || propertyKey == SHOW_KEYBOARD_CALLBACK) { + if (propertyKey == BOTTOM_OFFSET_PX || propertyKey == SHOW_KEYBOARD_CALLBACK + || propertyKey == KEYBOARD_TOGGLE_VISIBLE) { return; } assert false : "Every property update needs to be handled explicitly!"; } @Override - public void onTabSelected(TabLayout.Tab tab) { - mModel.set(ACTIVE_TAB, tab.getPosition()); + public void onActiveTabChanged(Integer activeTab) { + mModel.set(KEYBOARD_TOGGLE_VISIBLE, activeTab != null); + if (activeTab == null) { + mVisibilityDelegate.onCloseAccessorySheet(); + updateVisibility(); + return; + } + mVisibilityDelegate.onChangeAccessorySheet(activeTab); } @Override - public void onTabUnselected(TabLayout.Tab tab) {} + public void onActiveTabReselected() { + closeSheet(); + } @Override - public void onTabReselected(TabLayout.Tab tab) { - if (mModel.get(ACTIVE_TAB) == null) { - mModel.set(ACTIVE_TAB, tab.getPosition()); - } else { - closeSheet(); - } + public void onTabsChanged() { + updateVisibility(); } private void closeSheet() { + assert mTabSwitcher.getActiveTab() != null; KeyboardAccessoryMetricsRecorder.recordSheetTrigger( - mModel.get(TABS).get(mModel.get(ACTIVE_TAB)).getRecordingType(), MANUAL_CLOSE); + mTabSwitcher.getActiveTab().getRecordingType(), MANUAL_CLOSE); + mModel.set(KEYBOARD_TOGGLE_VISIBLE, false); mVisibilityDelegate.onOpenKeyboard(); // This will close the active tab gently. } boolean hasContents() { - return mModel.get(ACTIONS).size() > 0 || mModel.get(TABS).size() > 0; + return mModel.get(ACTIONS).size() > 0 || mTabSwitcher.hasTabs(); } private boolean shouldShowAccessory() { - if (!mShowIfNotEmpty && mModel.get(ACTIVE_TAB) == null) return false; + if (!mShowIfNotEmpty && mTabSwitcher.getActiveTab() == null) return false; return hasContents(); } @@ -206,6 +185,6 @@ } public boolean hasActiveTab() { - return mModel.get(VISIBLE) && mModel.get(ACTIVE_TAB) != null; + return mModel.get(VISIBLE) && mTabSwitcher.getActiveTab() != null; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryMetricsRecorder.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryMetricsRecorder.java index a548189..3e02394 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryMetricsRecorder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryMetricsRecorder.java
@@ -58,9 +58,12 @@ private final Set<Integer> mRecordedBarBuckets = new HashSet<>(); private final Set<Integer> mRecordedActionImpressions = new HashSet<>(); private final PropertyModel mModel; + private final KeyboardAccessoryCoordinator.TabSwitchingDelegate mTabSwitcher; - AccessoryBarObserver(PropertyModel keyboardAccessoryModel) { + AccessoryBarObserver(PropertyModel keyboardAccessoryModel, + KeyboardAccessoryCoordinator.TabSwitchingDelegate tabSwitcher) { mModel = keyboardAccessoryModel; + mTabSwitcher = tabSwitcher; } @Override @@ -70,8 +73,7 @@ if (mModel.get(KeyboardAccessoryProperties.VISIBLE)) { recordFirstImpression(); maybeRecordBarBucket(AccessoryBarContents.WITH_AUTOFILL_SUGGESTIONS); - recordUnrecordedList(mModel.get(KeyboardAccessoryProperties.TABS), 0, - mModel.get(KeyboardAccessoryProperties.TABS).size()); + maybeRecordBarBucket(AccessoryBarContents.WITH_TABS); recordUnrecordedList(mModel.get(KeyboardAccessoryProperties.ACTIONS), 0, mModel.get(KeyboardAccessoryProperties.ACTIONS).size()); } else { @@ -80,9 +82,8 @@ } return; } - if (propertyKey == KeyboardAccessoryProperties.ACTIVE_TAB - || propertyKey == KeyboardAccessoryProperties.BOTTOM_OFFSET_PX - || propertyKey == KeyboardAccessoryProperties.TAB_SELECTION_CALLBACKS + if (propertyKey == KeyboardAccessoryProperties.BOTTOM_OFFSET_PX + || propertyKey == KeyboardAccessoryProperties.KEYBOARD_TOGGLE_VISIBLE || propertyKey == KeyboardAccessoryProperties.SHOW_KEYBOARD_CALLBACK) { return; } @@ -99,10 +100,6 @@ */ private void recordUnrecordedList(ListObservable list, int first, int count) { if (!mModel.get(KeyboardAccessoryProperties.VISIBLE)) return; - if (list == mModel.get(KeyboardAccessoryProperties.TABS)) { - maybeRecordBarBucket(AccessoryBarContents.WITH_TABS); - return; - } if (list == mModel.get(KeyboardAccessoryProperties.ACTIONS)) { // Remove all actions that were changed, so changes are treated as new recordings. for (int index = first; index < first + count; ++index) { @@ -114,6 +111,7 @@ for (int index = first; index < first + count; ++index) { KeyboardAccessoryData.Action action = mModel.get(KeyboardAccessoryProperties.ACTIONS).get(index); + if (action.getActionType() == AccessoryAction.TAB_SWITCHER) continue; // Ignore! maybeRecordBarBucket( action.getActionType() == AccessoryAction.AUTOFILL_SUGGESTION ? AccessoryBarContents.WITH_AUTOFILL_SUGGESTIONS @@ -189,7 +187,7 @@ mModel.get(KeyboardAccessoryProperties.ACTIONS), AccessoryAction.AUTOFILL_SUGGESTION); case AccessoryBarContents.WITH_TABS: - return mModel.get(KeyboardAccessoryProperties.TABS).size() > 0; + return mTabSwitcher.hasTabs(); case AccessoryBarContents.ANY_CONTENTS: // Intentional fallthrough. case AccessoryBarContents.NO_CONTENTS: return true; // Logged on first impression. @@ -203,11 +201,11 @@ * Registers an observer to the given model that records changes for all properties. * @param keyboardAccessoryModel The observable {@link KeyboardAccessoryProperties}. */ - static void registerKeyboardAccessoryModelMetricsObserver( - PropertyModel keyboardAccessoryModel) { - AccessoryBarObserver observer = new AccessoryBarObserver(keyboardAccessoryModel); + static void registerKeyboardAccessoryModelMetricsObserver(PropertyModel keyboardAccessoryModel, + KeyboardAccessoryCoordinator.TabSwitchingDelegate tabSwitcher) { + AccessoryBarObserver observer = + new AccessoryBarObserver(keyboardAccessoryModel, tabSwitcher); keyboardAccessoryModel.addObserver(observer); - keyboardAccessoryModel.get(KeyboardAccessoryProperties.TABS).addObserver(observer); keyboardAccessoryModel.get(KeyboardAccessoryProperties.ACTIONS).addObserver(observer); } @@ -236,7 +234,8 @@ } if (propertyKey == AccessorySheetProperties.ACTIVE_TAB_INDEX || propertyKey == AccessorySheetProperties.HEIGHT - || propertyKey == AccessorySheetProperties.TOP_SHADOW_VISIBLE) { + || propertyKey == AccessorySheetProperties.TOP_SHADOW_VISIBLE + || propertyKey == AccessorySheetProperties.PAGE_CHANGE_LISTENER) { return; } assert false : "Every property update needs to be handled explicitly!";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryModernViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryModernViewBinder.java index 8222bce..c99a7ad 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryModernViewBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryModernViewBinder.java
@@ -4,7 +4,7 @@ package org.chromium.chrome.browser.autofill.keyboard_accessory; -import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.ACTIVE_TAB; +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.KEYBOARD_TOGGLE_VISIBLE; import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.SHOW_KEYBOARD_CALLBACK; import android.view.LayoutInflater; @@ -12,7 +12,6 @@ import android.view.ViewGroup; import org.chromium.chrome.R; -import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData.Action; import org.chromium.chrome.browser.modelutil.PropertyKey; import org.chromium.chrome.browser.modelutil.PropertyModel; @@ -35,15 +34,15 @@ .inflate( R.layout.keyboard_accessory_suggestion, parent, false)); case AccessoryAction.TAB_SWITCHER: - return new ModernActionViewHolder( + return new ModernActionViewHolder(( LayoutInflater.from(parent.getContext()) - .inflate(R.layout.keyboard_accessory_tabs, parent, false)); + .inflate(R.layout.keyboard_accessory_tabs, parent, false))); } return KeyboardAccessoryViewBinder.ActionViewHolder.create(parent, viewType); } @Override - public void bind(Action action) { + public void bind(KeyboardAccessoryData.Action action) { if (action.getActionType() == AccessoryAction.TAB_SWITCHER) return; super.bind(action); } @@ -54,8 +53,8 @@ assert view instanceof KeyboardAccessoryModernView; KeyboardAccessoryModernView modernView = (KeyboardAccessoryModernView) view; boolean wasBound = KeyboardAccessoryViewBinder.bindInternal(model, modernView, propertyKey); - if (propertyKey == ACTIVE_TAB) { - modernView.setKeyboardToggleVisibility(model.get(ACTIVE_TAB) != null); + if (propertyKey == KEYBOARD_TOGGLE_VISIBLE) { + modernView.setKeyboardToggleVisibility(model.get(KEYBOARD_TOGGLE_VISIBLE)); } else if (propertyKey == SHOW_KEYBOARD_CALLBACK) { modernView.setShowKeyboardCallback(model.get(SHOW_KEYBOARD_CALLBACK)); } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryProperties.java index f8e0dbf..01247c0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryProperties.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryProperties.java
@@ -4,8 +4,6 @@ package org.chromium.chrome.browser.autofill.keyboard_accessory; -import android.support.design.widget.TabLayout; - import org.chromium.chrome.browser.modelutil.ListModel; import org.chromium.chrome.browser.modelutil.PropertyModel.ReadableObjectPropertyKey; import org.chromium.chrome.browser.modelutil.PropertyModel.WritableBooleanPropertyKey; @@ -15,21 +13,17 @@ /** * As model of the keyboard accessory component, this class holds the data relevant to the visual * state of the accessory. - * This includes the visibility of the accessory in general, any available tabs and actions. - * Whenever the state changes, it notifies its listeners - like the - * {@link KeyboardAccessoryMediator} or the ModelChangeProcessor. + * This includes the visibility of the accessory, its relative position and actions. Whenever the + * state changes, it notifies its listeners - like the {@link KeyboardAccessoryMediator} or a + * ModelChangeProcessor. */ class KeyboardAccessoryProperties { static final ReadableObjectPropertyKey<ListModel<KeyboardAccessoryData.Action>> ACTIONS = new ReadableObjectPropertyKey<>(); - static final ReadableObjectPropertyKey<ListModel<KeyboardAccessoryData.Tab>> TABS = - new ReadableObjectPropertyKey<>(); static final WritableBooleanPropertyKey VISIBLE = new WritableBooleanPropertyKey(); static final WritableIntPropertyKey BOTTOM_OFFSET_PX = new WritableIntPropertyKey(); - static final /* @Nullable */ WritableObjectPropertyKey<Integer> ACTIVE_TAB = - new WritableObjectPropertyKey<>(); - static final WritableObjectPropertyKey<TabLayout.OnTabSelectedListener> - TAB_SELECTION_CALLBACKS = new WritableObjectPropertyKey<>(); + static final WritableBooleanPropertyKey KEYBOARD_TOGGLE_VISIBLE = + new WritableBooleanPropertyKey(); static final WritableObjectPropertyKey<Runnable> SHOW_KEYBOARD_CALLBACK = new WritableObjectPropertyKey<>();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutCoordinator.java new file mode 100644 index 0000000..7dbc5ef0 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutCoordinator.java
@@ -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. + +package org.chromium.chrome.browser.autofill.keyboard_accessory; + +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryTabLayoutProperties.ACTIVE_TAB; +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryTabLayoutProperties.TABS; +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryTabLayoutProperties.TAB_SELECTION_CALLBACKS; + +import android.support.design.widget.TabLayout; +import android.support.v4.view.ViewPager; + +import org.chromium.base.VisibleForTesting; +import org.chromium.chrome.browser.modelutil.ListModel; +import org.chromium.chrome.browser.modelutil.ListModelChangeProcessor; +import org.chromium.chrome.browser.modelutil.PropertyModel; +import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor; + +/** + * This component reflects the state of selected tabs in the keyboard accessory. It can be assigned + * to multiple {@link TabLayout}s and will keep them in sync. + */ +class KeyboardAccessoryTabLayoutCoordinator { + private final PropertyModel mModel = + new PropertyModel.Builder(TABS, ACTIVE_TAB, TAB_SELECTION_CALLBACKS) + .with(TABS, new ListModel<>()) + .with(ACTIVE_TAB, null) + .build(); + private final KeyboardAccessoryTabLayoutMediator mMediator; + + /** + * This observer gets notified when a tab get selected, reselected or when any tab changes. + */ + public interface AccessoryTabObserver { + /** + * Called when the active tab changes. + * @param activeTab The index of the active tab. + */ + void onActiveTabChanged(Integer activeTab); + + /** + * Called when an active tab is selected again. This only triggers if the selected tab is + * the {@link KeyboardAccessoryTabLayoutProperties#ACTIVE_TAB} in the tab layout model. + * Therefore, whenever {@link TabLayout.OnTabSelectedListener#onTabReselected} is called, + * either this function or {@link #onActiveTabChanged(Integer)} is called. Never both. + */ + void onActiveTabReselected(); + + /** + * Called when tabs are inserted, removed or changed. + */ + void onTabsChanged(); + } + + /** + * Creates the {@link KeyboardAccessoryTabLayoutViewBinder} that is linked to the + * {@link ListModelChangeProcessor} that connects the given + * {@link KeyboardAccessoryTabLayoutView} to the given tab list. + * @param model the {@link PropertyModel} with {@link KeyboardAccessoryTabLayoutProperties}. + * @param inflatedView the {@link KeyboardAccessoryTabLayoutView}. + * @return Returns a fully initialized and wired {@link KeyboardAccessoryTabLayoutView}. + */ + static KeyboardAccessoryTabLayoutViewBinder createTabViewBinder( + PropertyModel model, KeyboardAccessoryTabLayoutView inflatedView) { + KeyboardAccessoryTabLayoutViewBinder tabViewBinder = + new KeyboardAccessoryTabLayoutViewBinder(); + model.get(TABS).addObserver( + new ListModelChangeProcessor<>(model.get(TABS), inflatedView, tabViewBinder)); + return tabViewBinder; + } + + /** + * Creates a new Tab Layout component that isn't assigned to any view yet. + */ + public KeyboardAccessoryTabLayoutCoordinator() { + mMediator = new KeyboardAccessoryTabLayoutMediator(mModel); + } + + /** + * Binds the given view to its model using the {@link KeyboardAccessoryTabLayoutViewBinder}. + * @param tabLayout A {@link TabLayout}. + */ + public void assignNewView(TabLayout tabLayout) { + mMediator.setPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); + PropertyModelChangeProcessor.create(mModel, (KeyboardAccessoryTabLayoutView) tabLayout, + KeyboardAccessoryTabLayoutViewBinder::bind); + } + + /** + * Returns a delegate that executes on several tab-related actions. + * @return A {@link KeyboardAccessoryCoordinator.TabSwitchingDelegate}. + */ + public KeyboardAccessoryCoordinator.TabSwitchingDelegate getTabSwitchingDelegate() { + return mMediator; + } + + /** + * Adds a {@link AccessoryTabObserver} that is notified about events emitted when a tab changes. + * @param accessoryTabObserver The component to be notified of tab changes. + */ + public void setTabObserver(AccessoryTabObserver accessoryTabObserver) { + mMediator.setTabObserver(accessoryTabObserver); + } + + /** + * Returns an OnPageChangeListener that remains the same even if the assigned views changes. + * This is useful if multiple views are bound to this component or if the view may temporarily + * be destroyed (like in a RecyclerView). + * @return A stable {@link ViewPager.OnPageChangeListener}. + */ + public ViewPager.OnPageChangeListener getStablePageChangeListener() { + return mMediator.getStableOnPageChangeListener(); + } + @VisibleForTesting + public PropertyModel getModelForTesting() { + return mModel; + } + + @VisibleForTesting + public KeyboardAccessoryTabLayoutMediator getMediatorForTesting() { + return mMediator; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutMediator.java new file mode 100644 index 0000000..28eb65d --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutMediator.java
@@ -0,0 +1,148 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.autofill.keyboard_accessory; + +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryTabLayoutProperties.ACTIVE_TAB; +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryTabLayoutProperties.TABS; +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryTabLayoutProperties.TAB_SELECTION_CALLBACKS; + +import android.support.annotation.Nullable; +import android.support.design.widget.TabLayout; +import android.support.v4.view.ViewPager; + +import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryTabLayoutCoordinator.AccessoryTabObserver; +import org.chromium.chrome.browser.modelutil.ListObservable; +import org.chromium.chrome.browser.modelutil.PropertyKey; +import org.chromium.chrome.browser.modelutil.PropertyModel; +import org.chromium.chrome.browser.modelutil.PropertyObservable; + +/** + * This mediator observes and changes a {@link PropertyModel} that contains the visual appearance of + * a {@link TabLayout}. It manages {@link ViewPager.OnPageChangeListener}s. + */ +class KeyboardAccessoryTabLayoutMediator + implements ListObservable.ListObserver<Void>, TabLayout.OnTabSelectedListener, + PropertyObservable.PropertyObserver<PropertyKey>, + KeyboardAccessoryCoordinator.TabSwitchingDelegate { + private final PropertyModel mModel; + private @Nullable AccessoryTabObserver mAccessoryTabObserver; + private ViewPager.OnPageChangeListener mPageChangeListener; + + KeyboardAccessoryTabLayoutMediator(PropertyModel model) { + mModel = model; + mModel.addObserver(this); + mModel.get(TABS).addObserver(this); + mModel.set(TAB_SELECTION_CALLBACKS, this); + } + + void setPageChangeListener(ViewPager.OnPageChangeListener onPageChangeListener) { + mPageChangeListener = onPageChangeListener; + } + + ViewPager.OnPageChangeListener getStableOnPageChangeListener() { + return new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int i, float v, int j) { + if (mPageChangeListener != null) mPageChangeListener.onPageScrolled(i, v, j); + } + + @Override + public void onPageSelected(int i) { + if (mPageChangeListener != null) mPageChangeListener.onPageSelected(i); + } + + @Override + public void onPageScrollStateChanged(int i) { + if (mPageChangeListener != null) mPageChangeListener.onPageScrollStateChanged(i); + } + }; + } + + @Override + public void onPropertyChanged( + PropertyObservable<PropertyKey> source, @Nullable PropertyKey propertyKey) { + if (propertyKey == ACTIVE_TAB) { + if (mAccessoryTabObserver != null) { + mAccessoryTabObserver.onActiveTabChanged(mModel.get(ACTIVE_TAB)); + } + return; + } + if (propertyKey == TABS || propertyKey == TAB_SELECTION_CALLBACKS) { + return; + } + assert false : "Every property update needs to be handled explicitly!"; + } + + @Override + public void addTab(KeyboardAccessoryData.Tab tab) { + mModel.get(TABS).add(tab); + } + + @Override + public void removeTab(KeyboardAccessoryData.Tab tab) { + mModel.get(TABS).remove(tab); + } + + @Override + public void setTabs(KeyboardAccessoryData.Tab[] tabs) { + mModel.get(TABS).set(tabs); + } + + @Override + public void closeActiveTab() { + mModel.set(ACTIVE_TAB, null); + } + + @Override + public @Nullable KeyboardAccessoryData.Tab getActiveTab() { + if (mModel.get(ACTIVE_TAB) == null) return null; + return mModel.get(TABS).get(mModel.get(ACTIVE_TAB)); + } + + @Override + public boolean hasTabs() { + return mModel.get(TABS).size() > 0; + } + + @Override + public void onItemRangeInserted(ListObservable source, int index, int count) { + assert source == mModel.get(TABS); + if (mAccessoryTabObserver != null) mAccessoryTabObserver.onTabsChanged(); + } + + @Override + public void onItemRangeRemoved(ListObservable source, int index, int count) { + assert source == mModel.get(TABS); + if (mAccessoryTabObserver != null) mAccessoryTabObserver.onTabsChanged(); + } + + @Override + public void onItemRangeChanged( + ListObservable<Void> source, int index, int count, @Nullable Void payload) { + assert source == mModel.get(TABS); + if (mAccessoryTabObserver != null) mAccessoryTabObserver.onTabsChanged(); + } + + @Override + public void onTabSelected(TabLayout.Tab tab) { + mModel.set(ACTIVE_TAB, tab.getPosition()); + } + + @Override + public void onTabUnselected(TabLayout.Tab tab) {} + + @Override + public void onTabReselected(TabLayout.Tab tab) { + if (mModel.get(ACTIVE_TAB) == null) { + mModel.set(ACTIVE_TAB, tab.getPosition()); + } else if (mAccessoryTabObserver != null) { + mAccessoryTabObserver.onActiveTabReselected(); + } + } + + public void setTabObserver(AccessoryTabObserver accessoryTabObserver) { + mAccessoryTabObserver = accessoryTabObserver; + } +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutProperties.java new file mode 100644 index 0000000..824bbc8 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutProperties.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.autofill.keyboard_accessory; + +import android.support.design.widget.TabLayout; + +import org.chromium.chrome.browser.modelutil.ListModel; +import org.chromium.chrome.browser.modelutil.PropertyModel.ReadableObjectPropertyKey; +import org.chromium.chrome.browser.modelutil.PropertyModel.WritableObjectPropertyKey; + +/** + * These properties are used to describe a model for the tab layout component as used in the + * keyboard accessory. The properties are describing all known tabs. + */ +class KeyboardAccessoryTabLayoutProperties { + static final ReadableObjectPropertyKey<ListModel<KeyboardAccessoryData.Tab>> TABS = + new ReadableObjectPropertyKey<>(); + static final /* @Nullable */ WritableObjectPropertyKey<Integer> ACTIVE_TAB = + new WritableObjectPropertyKey<>(); + static final WritableObjectPropertyKey<TabLayout.OnTabSelectedListener> + TAB_SELECTION_CALLBACKS = new WritableObjectPropertyKey<>(); + + private KeyboardAccessoryTabLayoutProperties() {} +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutView.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutView.java new file mode 100644 index 0000000..75f5074 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutView.java
@@ -0,0 +1,99 @@ +// 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.content.Context; +import android.graphics.drawable.Drawable; +import android.support.annotation.Nullable; +import android.support.annotation.StringRes; +import android.support.design.widget.TabLayout; +import android.support.v4.graphics.drawable.DrawableCompat; +import android.util.AttributeSet; + +import org.chromium.chrome.R; + +/** + * A {@link TabLayout} containing the tabs in the keyboard accessory. + */ +public class KeyboardAccessoryTabLayoutView extends TabLayout { + /** + * Constructor for inflating from XML. + */ + public KeyboardAccessoryTabLayoutView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + /** + * Creates a new tab and appends it to the end of the tab layout at the start of the bar. + * @param icon The icon to be displayed in the tab bar. + * @param contentDescription The contentDescription to be used for the tab icon. + */ + void addTabAt(int position, Drawable icon, CharSequence contentDescription) { + TabLayout.Tab tab = newTab(); + tab.setIcon(icon.mutate()); // mutate() needed to change the active tint. + DrawableCompat.setTint(tab.getIcon(), getResources().getColor(R.color.default_icon_color)); + tab.setContentDescription(contentDescription); + addTab(tab, position, false); + } + + /** + * Removes the tab at the given position if it exists. If this isn't possible, it usually means + * the call was attempted before inflation (this is usually handled by the lazyMCP flushing all + * changes after inflation -- no further action needed). + * @param position The position of the tab to remove. + */ + void tryToRemoveTabAt(int position) { + TabLayout.Tab tab = getTabAt(position); + if (tab == null) return; // The tab was already removed. + removeTab(tab); + } + + /** + * This layout shouldn't have too many listeners so prefer this method over + * {@link #addOnTabSelectedListener(OnTabSelectedListener)} in order to keep only the latest + * listener. + * @param tabSelectionCallbacks A {@link OnTabSelectedListener}. + */ + void setTabSelectionAdapter(TabLayout.OnTabSelectedListener tabSelectionCallbacks) { + clearOnTabSelectedListeners(); + addOnTabSelectedListener(tabSelectionCallbacks); + } + + /** + * Marks only the given tab with the active tab color and resets all others. + * @param activeTab The active tab to change. If null, all tabs are reset. + */ + void setActiveTabColor(@Nullable Integer activeTab) { + for (int i = getTabCount() - 1; i >= 0; i--) { + TabLayout.Tab t = getTabAt(i); + if (t == null || t.getIcon() == null) continue; + int activeState = android.R.attr.state_selected; + if (activeTab == null || i != activeTab) activeState *= -1; // This means unselected. + DrawableCompat.setTint(t.getIcon(), + getTabTextColors().getColorForState( + new int[] {activeState}, getTabTextColors().getDefaultColor())); + } + } + + /** + * Sets a description for the tab at the given position if the tab exists. Noop otherwise. + * @param i The index of the tab to add a description to. + * @param description A {@link String} describing the tab, e.g. for accessibility. + */ + void setTabDescription(int i, String description) { + TabLayout.Tab tab = getTabAt(i); + if (tab != null) tab.setContentDescription(description); + } + + /** + * Sets a description for the tab at the given position if the tab exists. Noop otherwise. + * @param i The index of the tab to add a description to. + * @param messageId A {@link StringRes} describing the tab, e.g. for accessibility. + */ + void setTabDescription(int i, @StringRes int messageId) { + TabLayout.Tab tab = getTabAt(i); + if (tab != null) tab.setContentDescription(messageId); + } +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutViewBinder.java new file mode 100644 index 0000000..0d1dbf1 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutViewBinder.java
@@ -0,0 +1,89 @@ +// 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 static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryTabLayoutProperties.ACTIVE_TAB; +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryTabLayoutProperties.TABS; +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryTabLayoutProperties.TAB_SELECTION_CALLBACKS; + +import android.support.design.widget.TabLayout; + +import org.chromium.chrome.R; +import org.chromium.chrome.browser.modelutil.ListModel; +import org.chromium.chrome.browser.modelutil.ListModelChangeProcessor; +import org.chromium.chrome.browser.modelutil.PropertyKey; +import org.chromium.chrome.browser.modelutil.PropertyModel; + +/** + * Stateless {@link ListModelChangeProcessor.ViewBinder} that binds a {@link ListModel}'s data to + * a {@link KeyboardAccessoryTabLayoutView}. + */ +class KeyboardAccessoryTabLayoutViewBinder + implements ListModelChangeProcessor.ViewBinder<ListModel<KeyboardAccessoryData.Tab>, + KeyboardAccessoryTabLayoutView> { + @Override + public void onItemsInserted(ListModel<KeyboardAccessoryData.Tab> model, + KeyboardAccessoryTabLayoutView view, int index, int count) { + assert count > 0 : "Tried to insert invalid amount of tabs - must be at least one."; + for (int i = index; i < index + count; i++) { + KeyboardAccessoryData.Tab tab = model.get(i); + view.addTabAt(i, tab.getIcon(), tab.getContentDescription()); + } + } + + @Override + public void onItemsRemoved(ListModel<KeyboardAccessoryData.Tab> model, + KeyboardAccessoryTabLayoutView view, int index, int count) { + assert count > 0 : "Tried to remove invalid amount of tabs - must be at least one."; + while (count-- > 0) { + view.tryToRemoveTabAt(index++); + } + } + + @Override + public void onItemsChanged(ListModel<KeyboardAccessoryData.Tab> model, + KeyboardAccessoryTabLayoutView view, int index, int count) { + // TODO(fhorschig): Implement fine-grained, ranged changes should the need arise. + updateAllTabs(view, model); + } + + private void updateAllTabs( + KeyboardAccessoryTabLayoutView view, ListModel<KeyboardAccessoryData.Tab> model) { + view.removeAllTabs(); + if (model.size() > 0) onItemsInserted(model, view, 0, model.size()); + } + + protected static void bind( + PropertyModel model, KeyboardAccessoryTabLayoutView view, PropertyKey propertyKey) { + if (propertyKey == TABS) { + KeyboardAccessoryTabLayoutCoordinator.createTabViewBinder(model, view) + .updateAllTabs(view, model.get(TABS)); + } else if (propertyKey == ACTIVE_TAB) { + view.setActiveTabColor(model.get(ACTIVE_TAB)); + setActiveTabHint(model, view); + } else if (propertyKey == TAB_SELECTION_CALLBACKS) { + // Don't add null as listener. It's a valid state but an invalid argument. + TabLayout.OnTabSelectedListener listener = model.get(TAB_SELECTION_CALLBACKS); + if (listener != null) view.setTabSelectionAdapter(listener); + } else { + assert false : "Every possible property update needs to be handled!"; + } + } + + private static void setActiveTabHint(PropertyModel model, KeyboardAccessoryTabLayoutView view) { + int activeTab = -1; + if (model.get(ACTIVE_TAB) != null) { + activeTab = model.get(ACTIVE_TAB); + } + for (int i = 0; i < model.get(TABS).size(); ++i) { + KeyboardAccessoryData.Tab tab = model.get(TABS).get(i); + if (activeTab == i) { + view.setTabDescription(i, R.string.keyboard_accessory_sheet_hide); + } else { + view.setTabDescription(i, tab.getContentDescription()); + } + } + } +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryView.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryView.java index bc55d91..71af35a1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryView.java
@@ -8,11 +8,6 @@ import android.content.Context; import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.support.annotation.StringRes; -import android.support.design.widget.TabLayout; -import android.support.v4.graphics.drawable.DrawableCompat; -import android.support.v4.view.ViewPager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; @@ -29,8 +24,7 @@ */ class KeyboardAccessoryView extends LinearLayout { protected RecyclerView mActionsView; - private TabLayout mTabLayout; - private TabLayout.TabLayoutOnPageChangeListener mPageChangeListener; + private KeyboardAccessoryTabLayoutView mTabLayout; private static class HorizontalDividerItemDecoration extends RecyclerView.ItemDecoration { private final int mHorizontalMargin; @@ -77,6 +71,10 @@ setSoundEffectsEnabled(false); } + KeyboardAccessoryTabLayoutView getTabLayout() { + return mTabLayout; + } + void setVisible(boolean visible) { if (visible) { show(); @@ -95,68 +93,6 @@ mActionsView.setAdapter(adapter); } - /** - * Creates a new tab and appends it to the end of the tab layout at the start of the bar. - * @param icon The icon to be displayed in the tab bar. - * @param contentDescription The contentDescription to be used for the tab icon. - */ - void addTabAt(int position, Drawable icon, CharSequence contentDescription) { - if (mTabLayout == null) return; // Inflation not done yet. Will be invoked again afterwards. - TabLayout.Tab tab = mTabLayout.newTab(); - tab.setIcon(icon.mutate()); // mutate() needed to change the active tint. - DrawableCompat.setTint(tab.getIcon(), getResources().getColor(R.color.default_icon_color)); - tab.setContentDescription(contentDescription); - mTabLayout.addTab(tab, position, false); - } - - void removeTabAt(int position) { - if (mTabLayout == null) return; // Inflation not done yet. Will be invoked again afterwards. - TabLayout.Tab tab = mTabLayout.getTabAt(position); - if (tab == null) return; // The tab was already removed. - mTabLayout.removeTab(tab); - } - - /** - * Removes all tabs. - */ - void clearTabs() { - if (mTabLayout == null) return; // Inflation not done yet. Will be invoked again afterwards. - mTabLayout.removeAllTabs(); - } - - ViewPager.OnPageChangeListener getPageChangeListener() { - if (mPageChangeListener == null) { - mPageChangeListener = new TabLayout.TabLayoutOnPageChangeListener(mTabLayout); - } - return mPageChangeListener; - } - - void setTabSelectionAdapter(TabLayout.OnTabSelectedListener tabSelectionCallbacks) { - mTabLayout.clearOnTabSelectedListeners(); - mTabLayout.addOnTabSelectedListener(tabSelectionCallbacks); - } - - void setActiveTabColor(Integer activeTab) { - for (int i = mTabLayout.getTabCount() - 1; i >= 0; i--) { - TabLayout.Tab t = mTabLayout.getTabAt(i); - if (t == null || t.getIcon() == null) continue; - int activeStateColor = (activeTab == null || i != activeTab) - ? R.color.default_icon_color - : R.color.default_icon_color_blue; - DrawableCompat.setTint(t.getIcon(), getResources().getColor(activeStateColor)); - } - } - - public void setTabDescription(int i, String description) { - TabLayout.Tab tab = mTabLayout.getTabAt(i); - if (tab != null) tab.setContentDescription(description); - } - - public void setTabDescription(int i, @StringRes int messageId) { - TabLayout.Tab tab = mTabLayout.getTabAt(i); - if (tab != null) tab.setContentDescription(messageId); - } - private void show() { bringToFront(); // Needs to overlay every component and the bottom sheet - like a keyboard. setVisibility(View.VISIBLE);
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 6635627..8245b25 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
@@ -5,15 +5,12 @@ package org.chromium.chrome.browser.autofill.keyboard_accessory; import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.ACTIONS; -import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.ACTIVE_TAB; import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.BOTTOM_OFFSET_PX; +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.KEYBOARD_TOGGLE_VISIBLE; import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.SHOW_KEYBOARD_CALLBACK; -import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.TABS; -import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.TAB_SELECTION_CALLBACKS; import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.VISIBLE; import android.os.Build; -import android.support.design.widget.TabLayout; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; @@ -23,9 +20,6 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData.Action; -import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData.Tab; -import org.chromium.chrome.browser.modelutil.ListModel; -import org.chromium.chrome.browser.modelutil.ListModelChangeProcessor; import org.chromium.chrome.browser.modelutil.PropertyKey; import org.chromium.chrome.browser.modelutil.PropertyModel; @@ -67,40 +61,6 @@ } } - static class TabViewBinder - implements ListModelChangeProcessor.ViewBinder<ListModel<Tab>, KeyboardAccessoryView> { - @Override - public void onItemsInserted( - ListModel<Tab> model, KeyboardAccessoryView view, int index, int count) { - assert count > 0 : "Tried to insert invalid amount of tabs - must be at least one."; - for (int i = index; i < index + count; i++) { - Tab tab = model.get(i); - view.addTabAt(i, tab.getIcon(), tab.getContentDescription()); - } - } - - @Override - public void onItemsRemoved( - ListModel<Tab> model, KeyboardAccessoryView view, int index, int count) { - assert count > 0 : "Tried to remove invalid amount of tabs - must be at least one."; - while (count-- > 0) { - view.removeTabAt(index++); - } - } - - @Override - public void onItemsChanged( - ListModel<Tab> model, KeyboardAccessoryView view, int index, int count) { - // TODO(fhorschig): Implement fine-grained, ranged changes should the need arise. - updateAllTabs(view, model); - } - - void updateAllTabs(KeyboardAccessoryView view, ListModel<Tab> model) { - view.clearTabs(); - if (model.size() > 0) onItemsInserted(model, view, 0, model.size()); - } - } - public static void bind( PropertyModel model, KeyboardAccessoryView view, PropertyKey propertyKey) { boolean wasBound = bindInternal(model, view, propertyKey); @@ -120,25 +80,14 @@ if (propertyKey == ACTIONS) { view.setActionsAdapter( KeyboardAccessoryCoordinator.createActionsAdapter(model.get(ACTIONS))); - } else if (propertyKey == TABS) { - KeyboardAccessoryCoordinator.createTabViewBinder(model, view) - .updateAllTabs(view, model.get(TABS)); } else if (propertyKey == VISIBLE) { - view.setActiveTabColor(model.get(ACTIVE_TAB)); - setActiveTabHint(model, view); view.setVisible(model.get(VISIBLE)); - } else if (propertyKey == ACTIVE_TAB) { - view.setActiveTabColor(model.get(ACTIVE_TAB)); - setActiveTabHint(model, view); } else if (propertyKey == BOTTOM_OFFSET_PX) { view.setBottomOffset(model.get(BOTTOM_OFFSET_PX)); - } else if (propertyKey == TAB_SELECTION_CALLBACKS) { - // Don't add null as listener. It's a valid state but an invalid argument. - TabLayout.OnTabSelectedListener listener = model.get(TAB_SELECTION_CALLBACKS); - if (listener == null) return true; - view.setTabSelectionAdapter(listener); } else if (propertyKey == SHOW_KEYBOARD_CALLBACK) { // No binding required. + } else if (propertyKey == KEYBOARD_TOGGLE_VISIBLE) { + // No binding required. } else { return false; } @@ -156,19 +105,4 @@ }); } } - - private static void setActiveTabHint(PropertyModel model, KeyboardAccessoryView view) { - int activeTab = -1; - if (model.get(ACTIVE_TAB) != null) { - activeTab = model.get(ACTIVE_TAB); - } - for (int i = 0; i < model.get(TABS).size(); ++i) { - Tab tab = model.get(TABS).get(i); - if (activeTab == i) { - view.setTabDescription(i, R.string.keyboard_accessory_sheet_hide); - } else { - view.setTabDescription(i, tab.getContentDescription()); - } - } - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingCoordinator.java index c8dbc28..a352ddd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingCoordinator.java
@@ -46,9 +46,6 @@ @VisibleForTesting void initialize(WindowAndroid windowAndroid, ViewProvider<KeyboardAccessoryView> barProvider, ViewProvider<AccessorySheetView> sheetProvider) { - sheetProvider.whenLoaded(accessorySheetView -> barProvider.whenLoaded(accessoryView -> { - accessorySheetView.addOnPageChangeListener(accessoryView.getPageChangeListener()); - })); mMediator.initialize(new KeyboardAccessoryCoordinator(mMediator, barProvider), new AccessorySheetCoordinator(sheetProvider), windowAndroid); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingMediator.java index ac9ce3b..48b8f54 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingMediator.java
@@ -155,6 +155,7 @@ mWindowAndroid = windowAndroid; mKeyboardAccessory = keyboardAccessory; mAccessorySheet = accessorySheet; + mAccessorySheet.setOnPageChangeListener(mKeyboardAccessory.getOnPageChangeListener()); setInsetObserverViewSupplier(mActivity::getInsetObserverView); LayoutManager manager = getLayoutManager(); if (manager != null) manager.addSceneChangeObserver(mTabSwitcherObserver);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java index 8c395c6..0b0e792 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java
@@ -506,6 +506,7 @@ // to display longer messages. Setting the max lines and hiding the feedback button are // hacks to give enough space to display long messages. mStatusMessageView.setMaxLines(4); + expandBottomSheet(); mBottomBar.findViewById(R.id.feedback_button).setVisibility(View.GONE); hideOverlay(); mTouchEventFilter.setVisibility(View.GONE);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTopBarDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTopBarDelegate.java index f376bf4..5a760efd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTopBarDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTopBarDelegate.java
@@ -67,14 +67,6 @@ } /** - * Gets the top bar content view, or null if it is not specified. - */ - @Nullable - public View getTopBarContentView() { - return mTopBarContentView; - } - - /** * Gets the {@link ViewGroup} of the top bar. If it has not been inflated, inflate it first. */ private ViewGroup getTopBarView() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java index 2922e68..486aa1f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java
@@ -88,6 +88,8 @@ @ToolbarVisibility private int mDefaultToolbarShadowVisibility; + // Whether the progress bar is enabled prior to any header customization. + private boolean mDefaultIsProgressBarEnabled; // Default height of the top control container prior to any header customization. private int mDefaultTopControlContainerHeight; private boolean mHasSetOverlayView; @@ -278,6 +280,7 @@ mDefaultToolbarVisibility = mActivity.getToolbarManager().getToolbarVisibility(); mDefaultToolbarShadowVisibility = mActivity.getToolbarManager().getToolbarShadowVisibility(); + mDefaultIsProgressBarEnabled = mActivity.getToolbarManager().isProgressBarEnabled(); mDefaultTopControlContainerHeight = mFullscreenManager.get().getTopControlsHeight(); mModuleCallback = null; @@ -376,11 +379,10 @@ isModuleManagedUrl ? View.GONE : mDefaultToolbarVisibility); mActivity.getToolbarManager().setToolbarShadowVisibility( isModuleManagedUrl ? View.GONE : mDefaultToolbarShadowVisibility); + mActivity.getToolbarManager().setProgressBarEnabled( + isModuleManagedUrl ? false : mDefaultIsProgressBarEnabled); mFullscreenManager.get().setTopControlsHeight( isModuleManagedUrl ? getTopBarHeight() : mDefaultTopControlContainerHeight); - mActivity.getToolbarManager().setProgressBarAnchorView(isModuleManagedUrl - ? mTopBarDelegate.get().getTopBarContentView() - : mActivity.getToolbarManager().getToolbarView()); } }
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 6a0c7c2..c7d6fa92 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
@@ -344,6 +344,7 @@ RecordHistogram.recordBooleanHistogram( "NewTabPage.MobileIsUserOnline", NetworkChangeNotifier.isOnline()); NewTabPageUma.recordLoadType(activity); + NewTabPageUma.recordContentSuggestionsDisplayStatus(); TraceEvent.end(TAG); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java index a871afc..fc16548 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java
@@ -11,6 +11,8 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.IntentHandler; +import org.chromium.chrome.browser.preferences.Pref; +import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.rappor.RapporServiceBridge; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; @@ -119,6 +121,20 @@ int NUM_ENTRIES = 4; } + @IntDef({ContentSuggestionsDisplayStatus.VISIBLE, ContentSuggestionsDisplayStatus.COLLAPSED, + ContentSuggestionsDisplayStatus.DISABLED_BY_POLICY, + ContentSuggestionsDisplayStatus.NUM_ENTRIES}) + + // These values are persisted to logs. Entries should not be renumbered and + // numeric values should never be reused. This maps directly to + // the ContentSuggestionsDisplayStatus enum defined in tools/metrics/enums.xml. + private @interface ContentSuggestionsDisplayStatus { + int VISIBLE = 0; + int COLLAPSED = 1; + int DISABLED_BY_POLICY = 2; + int NUM_ENTRIES = 3; + } + /** The NTP was loaded in a cold startup. */ private static final int LOAD_TYPE_COLD_START = 0; @@ -287,6 +303,24 @@ } /** + * Records Content Suggestions Display Status when NTPs opened. + */ + public static void recordContentSuggestionsDisplayStatus() { + @ContentSuggestionsDisplayStatus + int status = ContentSuggestionsDisplayStatus.VISIBLE; + if (!PrefServiceBridge.getInstance().getBoolean(Pref.NTP_ARTICLES_SECTION_ENABLED)) { + // Disabled by policy. + status = ContentSuggestionsDisplayStatus.DISABLED_BY_POLICY; + } else if (!PrefServiceBridge.getInstance().getBoolean(Pref.NTP_ARTICLES_LIST_VISIBLE)) { + // Articles are collapsed. + status = ContentSuggestionsDisplayStatus.COLLAPSED; + } + + RecordHistogram.recordEnumeratedHistogram("ContentSuggestions.Feed.DisplayStatus", status, + ContentSuggestionsDisplayStatus.NUM_ENTRIES); + } + + /** * Records the number of new NTPs opened in a new tab. Use through * {@link NewTabPageUma#monitorNTPCreation(TabModelSelector)}. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index bf34a844..cae5c8c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -212,6 +212,7 @@ private boolean mNativeLibraryReady; private boolean mTabRestoreCompleted; + private boolean mProgressBarEnabled; private AppMenuButtonHelper mAppMenuButtonHelper; @@ -1471,7 +1472,7 @@ * @return One of View.VISIBLE, View.INVISIBLE, or View.GONE. */ public int getToolbarVisibility() { - View toolbar = getToolbarView(); + View toolbar = mControlContainer.findViewById(R.id.toolbar); return (toolbar != null) ? toolbar.getVisibility() : View.GONE; } @@ -1479,19 +1480,11 @@ * Sets the visibility of the Toolbar. */ public void setToolbarVisibility(int visibility) { - View toolbar = getToolbarView(); + View toolbar = mControlContainer.findViewById(R.id.toolbar); if (toolbar != null) toolbar.setVisibility(visibility); } /** - * Gets the Toolbar view. - */ - @Nullable - public View getToolbarView() { - return mControlContainer.findViewById(R.id.toolbar); - } - - /** * Sets the drawable that the close button shows, or hides it if {@code drawable} is * {@code null}. */ @@ -1765,17 +1758,18 @@ } /** - * @param enabled Whether the progress bar is enabled. + * @return Whether the progress bar is enabled. */ - public void setProgressBarEnabled(boolean enabled) { - mToolbar.setProgressBarEnabled(enabled); + public boolean isProgressBarEnabled() { + return mProgressBarEnabled; } /** - * @param anchor The view to use as an anchor. + * @param enabled Whether the progress bar is enabled. */ - public void setProgressBarAnchorView(@Nullable View anchor) { - mToolbar.setProgressBarAnchorView(anchor); + public void setProgressBarEnabled(boolean enabled) { + mProgressBarEnabled = enabled; + mToolbar.setProgressBarEnabled(enabled); } private boolean shouldShowCursorInLocationBar() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarMediator.java index 0107238..490c9b5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BrowsingModeBottomToolbarMediator.java
@@ -143,8 +143,8 @@ (baseColor & 0x00FFFFFF) | ((int) (DUET_IPH_BUBBLE_ALPHA_FRACTION * 255) << 24); FeatureHighlightProvider.getInstance().buildForView(activity, anchor, - R.string.iph_duet_start_search, FeatureHighlightProvider.TextAlignment.CENTER, - R.style.WhiteTitle1, R.string.iph_duet_icons_moved, + R.string.iph_duet_title, FeatureHighlightProvider.TextAlignment.CENTER, + R.style.WhiteTitle1, R.string.iph_duet_description, FeatureHighlightProvider.TextAlignment.CENTER, R.style.WhiteBody, finalColor, DUET_IPH_BUBBLE_SHOW_DURATION_MS);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java index 2b4673f..166456c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java
@@ -108,6 +108,7 @@ if (isNativeLibraryReady() && mProgressBar.getParent() != null) { mProgressBar.initializeAnimation(); } + mProgressBar.setTopMargin(getProgressBarTopMargin()); // Since this only needs to happen once, remove this listener from the view. removeOnLayoutChangeListener(this); @@ -140,6 +141,16 @@ void destroy() {} /** + * Get the top margin of the progress bar relative to the toolbar layout. This is used to set + * the position of the progress bar (either top or bottom of the toolbar). + * @return The top margin of the progress bar. + */ + int getProgressBarTopMargin() { + return getHeight() + - getResources().getDimensionPixelSize(R.dimen.toolbar_progress_bar_height); + } + + /** * Set the height that the progress bar should be. * @return The progress bar height in px. */ @@ -151,7 +162,8 @@ * @return A progress bar for Chrome to use. */ ToolbarProgressBar createProgressBar() { - return new ToolbarProgressBar(getContext(), getProgressBarHeight(), this, false); + return new ToolbarProgressBar( + getContext(), getProgressBarHeight(), getProgressBarTopMargin(), false); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java index 3b31138..464b614 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java
@@ -136,6 +136,12 @@ mToolbarButtons = new ImageButton[] {mBackButton, mForwardButton, mReloadButton}; } + @Override + protected int getProgressBarTopMargin() { + int tabStripHeight = getResources().getDimensionPixelSize(R.dimen.tab_strip_height); + return super.getProgressBarTopMargin() + tabStripHeight; + } + /** * Sets up key listeners after native initialization is complete, so that we can invoke * native functions.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java index 21e5b21..d7e651d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
@@ -470,13 +470,6 @@ } /** - * @param anchor The view to use as an anchor. - */ - public void setProgressBarAnchorView(@Nullable View anchor) { - mToolbarProvider.whenLoaded(toolbar -> getProgressBar().setAnchorView(anchor)); - } - - /** * Starts load progress. */ public void startLoadProgress() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/PageViewObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/PageViewObserver.java index 80b949d3..d6ad453 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/PageViewObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/PageViewObserver.java
@@ -4,20 +4,113 @@ package org.chromium.chrome.browser.usage_stats; +import android.app.Activity; +import android.net.Uri; +import android.webkit.URLUtil; + +import org.chromium.chrome.browser.tab.EmptyTabObserver; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.Tab.TabHidingType; +import org.chromium.chrome.browser.tab.TabObserver; +import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver; /** * Class that observes url and tab changes in order to track when browsing stops and starts for each - * visited fdqn. + * visited fully-qualified domain name (FQDN). */ public class PageViewObserver { - private TabModelSelector mTabModelSelector; - private EventTracker mEventTracker; + private final Activity mActivity; + private final TabModelSelectorTabModelObserver mTabModelObserver; + private final TabModelSelector mTabModelSelector; + private final TabObserver mTabObserver; + private final EventTracker mEventTracker; - public PageViewObserver(TabModelSelector tabModelSelector, EventTracker eventTracker) { + private Tab mCurrentTab; + private String mLastFqdn; + + public PageViewObserver( + Activity activity, TabModelSelector tabModelSelector, EventTracker eventTracker) { + mActivity = activity; mTabModelSelector = tabModelSelector; mEventTracker = eventTracker; + mTabObserver = new EmptyTabObserver() { + @Override + public void onShown(Tab tab, @TabSelectionType int type) { + updateUrl(tab.getUrl()); + } + + @Override + public void onHidden(Tab tab, @TabHidingType int type) { + updateUrl(null); + } + + @Override + public void onUpdateUrl(Tab tab, String url) { + assert tab == mCurrentTab; + + updateUrl(url); + } + }; + + mTabModelObserver = new TabModelSelectorTabModelObserver(tabModelSelector) { + @Override + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { + assert tab != null; + if (tab == mCurrentTab) return; + + switchObserverToTab(tab); + updateUrl(tab.getUrl()); + } + + @Override + public void willCloseTab(Tab tab, boolean animate) { + assert tab != null; + if (tab != mCurrentTab) return; + + updateUrl(null); + switchObserverToTab(null); + } + + @Override + public void tabRemoved(Tab tab) { + assert tab != null; + if (tab != mCurrentTab) return; + + updateUrl(null); + switchObserverToTab(null); + } + }; + + switchObserverToTab(tabModelSelector.getCurrentTab()); } - // TODO(pnoland): implement page view observation and push events to EventTracker. -} + private void updateUrl(String newUrl) { + String newFqdn = newUrl == null ? "" : Uri.parse(newUrl).getHost(); + if (mLastFqdn != null && mLastFqdn.equals(newFqdn)) return; + + if (mLastFqdn != null) { + mEventTracker.addWebsiteEvent(new WebsiteEvent( + System.currentTimeMillis(), mLastFqdn, WebsiteEvent.EventType.STOP)); + mLastFqdn = null; + } + + if (!URLUtil.isHttpUrl(newUrl) && !URLUtil.isHttpsUrl(newUrl)) return; + + mLastFqdn = newFqdn; + mEventTracker.addWebsiteEvent(new WebsiteEvent( + System.currentTimeMillis(), mLastFqdn, WebsiteEvent.EventType.START)); + } + + private void switchObserverToTab(Tab tab) { + if (mCurrentTab != tab && mCurrentTab != null) { + mCurrentTab.removeObserver(mTabObserver); + } + + mCurrentTab = tab; + if (mCurrentTab != null) { + mCurrentTab.addObserver(mTabObserver); + } + } +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/UsageStatsService.java b/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/UsageStatsService.java index 531fbb9..c09d885 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/UsageStatsService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/UsageStatsService.java
@@ -49,7 +49,7 @@ public PageViewObserver createPageViewObserver( TabModelSelector tabModelSelector, Activity activity) { ThreadUtils.assertOnUiThread(); - return new PageViewObserver(tabModelSelector, mEventTracker); + return new PageViewObserver(activity, tabModelSelector, mEventTracker); } /** @return Whether the user has authorized DW to access usage stats data. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBar.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBar.java index 92347710..236bbc5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBar.java
@@ -12,9 +12,7 @@ import android.content.Context; import android.graphics.Color; import android.os.Build; -import android.support.annotation.Nullable; import android.support.v4.view.ViewCompat; -import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; import android.view.animation.AccelerateInterpolator; @@ -118,16 +116,6 @@ /** Whether or not the progress bar is attached to the window. */ private boolean mIsAttachedToWindow; - /** The progress bar's anchor view. */ - @Nullable - private View mAnchorView; - - /** The progress bar's height. */ - private final int mProgressBarHeight; - - private final OnLayoutChangeListener mOnLayoutChangeListener = (view, left, top, right, bottom, - oldLeft, oldTop, oldRight, oldBottom) -> updateTopMargin(); - private final Runnable mStartSmoothIndeterminate = new Runnable() { @Override public void run() { @@ -232,16 +220,15 @@ * * @param context The application environment. * @param height The height of the progress bar in px. - * @param anchor The view to use as an anchor. + * @param topMargin The top margin of the progress bar. * @param useStatusBarColorAsBackground Whether or not to use the status bar color as the * background of the toolbar. */ public ToolbarProgressBar( - Context context, int height, View anchor, boolean useStatusBarColorAsBackground) { + Context context, int height, int topMargin, boolean useStatusBarColorAsBackground) { super(context, height); - mProgressBarHeight = height; setAlpha(0.0f); - setAnchorView(anchor); + mMarginTop = topMargin; mUseStatusBarColorAsBackground = useStatusBarColorAsBackground; mAnimationLogic = new ProgressAnimationSmooth(); @@ -254,16 +241,12 @@ * Set the top progress bar's top margin. * @param topMargin The top margin of the progress bar in px. */ - private void setTopMargin(int topMargin) { + public void setTopMargin(int topMargin) { mMarginTop = topMargin; if (mIsAttachedToWindow) { assert getLayoutParams() != null; ((ViewGroup.MarginLayoutParams) getLayoutParams()).topMargin = mMarginTop; - if (mAnimatingView != null && mAnimatingView.getLayoutParams() != null) { - ((ViewGroup.MarginLayoutParams) mAnimatingView.getLayoutParams()).topMargin = - mMarginTop; - } } } @@ -592,42 +575,4 @@ public Animator getIndeterminateAnimatorForTesting() { return mSmoothProgressAnimator; } - - /** - * Sets the progress bar's anchor view. This progress bar will always be positioned relative to - * the anchor view when shown. - * - * @param anchor The view to use as an anchor. - */ - public void setAnchorView(@Nullable View anchor) { - if (mAnchorView == anchor) return; - - if (mAnchorView != null) { - mAnchorView.removeOnLayoutChangeListener(mOnLayoutChangeListener); - } - mAnchorView = anchor; - updateTopMargin(); - if (mAnchorView != null) { - mAnchorView.addOnLayoutChangeListener(mOnLayoutChangeListener); - } - } - - /** - * Updates the progress bar's top margin. The only time this is a NOOP is if the margin remains - * the same. - */ - private void updateTopMargin() { - int topMargin = (mAnchorView != null ? mAnchorView.getBottom() : 0) - mProgressBarHeight - + getTabStripHeight(); - if (mMarginTop != topMargin) { - setTopMargin(topMargin); - } - } - - /** - * @return The height of the tab strip. Return 0 for toolbars that do not have a tabstrip. - */ - private int getTabStripHeight() { - return getResources().getDimensionPixelSize(R.dimen.tab_strip_height); - } }
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 31c0efd..2da1535 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -2024,8 +2024,8 @@ <message name="IDS_CONTEXTMENU_OPEN_IMAGE_IN_NEW_TAB" desc="Context sensitive menu item for opening/viewing the selected image in a new tab. [CHAR-LIMIT=30]"> Open image in new tab </message> - <message name="IDS_CONTEXTMENU_OPEN_IMAGE_IN_EPHEMERAL_TAB" desc="Context-sensitive menu item to open a quick preview of the selected image. In English we're currently calling this 'Sneak peek' which implies that it's a quick preview without commitment (to making a new Tab). We're also labeling it *New* to draw attention to it when first released. The selected link will open in an overlay panel on top of the current tab which will go away easily too. [CHAR-LIMIT=30]"> - *New* Sneak peek + <message name="IDS_CONTEXTMENU_OPEN_IMAGE_IN_EPHEMERAL_TAB" desc="Context-sensitive menu item to open a quick preview of the selected image. This is an 'image' variation of the plain 'Sneak peek' menu item. In English we're currently calling this 'Sneak peek image' which implies that it's a quick preview without commitment (to making a new Tab). We're also labeling it *New* to draw attention to it when first released. The selected image link will open in an overlay panel on top of the current tab which will go away easily too. [CHAR-LIMIT=30]"> + *New* Sneak peek image </message> <message name="IDS_CONTEXTMENU_LOAD_ORIGINAL_IMAGE" desc="Context sensitive menu item for Lite mode low fidelity placeholder images that loads the original version in place. [CHAR-LIMIT=30]"> Load image @@ -3849,11 +3849,11 @@ </message> <!-- Chrome Duet --> - <message name="IDS_IPH_DUET_START_SEARCH" desc="The in-product help message for the split toolbar experiment that explains that the user can start a new web search using the focused icon."> - Tap here to quickly begin a search + <message name="IDS_IPH_DUET_TITLE" desc="This string appears in an overlay that explains a new UI to users. 'Search' refers to searching the web, and 'explore' refers to Chrome's suggested content."> + Search & explore </message> - <message name="IDS_IPH_DUET_ICONS_MOVED" desc="The in-product help message for the split toolbar experiment that explains that the user's icons (menu button, tab switcher button, and home button) have moved to the bottom of the screen."> - Easily navigate anywhere in Chrome using the buttons at the bottom of your screen + <message name="IDS_IPH_DUET_DESCRIPTION" desc="This string appears in an overlay that explains a new UI to users. 'From here' is a generic directional cue: don't worry about the direction, as it is clarified by the way the overlay is shown."> + From here, you can search the web, share with friends, and see open pages </message> <!-- Photo picker --> @@ -3911,13 +3911,13 @@ <!-- Autofill Assistant --> <message name="IDS_AUTOFILL_ASSISTANT_ONBOARDING_TITLE" desc="Onboarding title for the autofill assistant."> - Google Assistant in Chrome + Google Assistant\nin Chrome </message> <message name="IDS_AUTOFILL_ASSISTANT_STOPPED" desc="Text label that is shown when stopping the Autofill Assistant."> Google Assistant in Chrome stopping </message> <message name="IDS_INIT_OK" desc="Init screen confirmation text."> - Let's go + I accept </message> <message name="IDS_AUTOFILL_ASSISTANT_INIT_MESSAGE" desc="Onboarding message describing autofill assistant's capability."> The Google Assistant saves you time by speeding you through the website's checkout. @@ -3930,7 +3930,7 @@ Assistant Triggered Checkout </message> <message name="IDS_AUTOFILL_ASSISTANT_GOOGLE_TERMS_DESCRIPTION" desc="Message linking to the Google terms and conditions for Fast Checkout."> - By continuing, you agree that Chrome will send data from Chrome Autofill, the site’s URL and its content to Google to provide this service. Visit Chrome settings to turn off Google Assistant in Chrome and Chrome Autofill. <ph name="BEGIN_LINK"><link></ph>Learn more<ph name="END_LINK"></link></ph> + By continuing, you agree that Chrome will send data from Chrome Autofill, the site’s URL and its content to Google to provide this service.\n\nVisit Chrome settings to turn off Google Assistant in Chrome and Chrome Autofill. <ph name="BEGIN_LINK"><link></ph>Read more<ph name="END_LINK"></link></ph> </message> <message name="IDS_AUTOFILL_ASSISTANT_GOOGLE_TERMS_URL" desc="URL for Google Autofill Assistant Terms of Service" translateable="false"> http://support.google.com/assistant?p=fast_checkout
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index e9fd8548..65f4325 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -117,6 +117,11 @@ "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryModernView.java", "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryModernViewBinder.java", "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryProperties.java", + "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutCoordinator.java", + "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutMediator.java", + "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutProperties.java", + "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutView.java", + "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutViewBinder.java", "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryView.java", "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryViewBinder.java", "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardExtensionSizeManager.java", @@ -1907,6 +1912,7 @@ "javatests/src/org/chromium/chrome/browser/autofill/PersonalDataManagerTest.java", "javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetViewTest.java", "javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/FakeKeyboard.java", + "javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutViewTest.java", "javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryViewTest.java", "javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingTestHelper.java", @@ -2360,6 +2366,7 @@ "junit/src/org/chromium/chrome/browser/ShortcutHelperTest.java", "junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetControllerTest.java", "junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryControllerTest.java", + "junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutControllerTest.java", "junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingControllerTest.java", "junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetControllerTest.java", "junit/src/org/chromium/chrome/browser/background_task_scheduler/NativeBackgroundTaskTest.java", @@ -2541,6 +2548,7 @@ if (enable_usage_stats) { chrome_junit_test_java_sources += [ "junit/src/org/chromium/chrome/browser/usage_stats/EventTrackerTest.java", + "junit/src/org/chromium/chrome/browser/usage_stats/PageViewObserverTest.java", ] }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutViewTest.java new file mode 100644 index 0000000..b54ab3d4 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutViewTest.java
@@ -0,0 +1,145 @@ +// 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 static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.isRoot; +import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription; + +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.core.AllOf.allOf; + +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryTabLayoutProperties.ACTIVE_TAB; +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryTabLayoutProperties.TABS; +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryTabLayoutProperties.TAB_SELECTION_CALLBACKS; +import static org.chromium.chrome.test.util.ViewUtils.VIEW_GONE; +import static org.chromium.chrome.test.util.ViewUtils.VIEW_INVISIBLE; +import static org.chromium.chrome.test.util.ViewUtils.VIEW_NULL; +import static org.chromium.chrome.test.util.ViewUtils.waitForView; + +import android.support.test.filters.MediumTest; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewStub; +import android.widget.ImageView; + +import org.hamcrest.Matcher; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.ThreadUtils; +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.ChromeSwitches; +import org.chromium.chrome.browser.ChromeTabbedActivity; +import org.chromium.chrome.browser.modelutil.ListModel; +import org.chromium.chrome.browser.modelutil.PropertyModel; +import org.chromium.chrome.test.ChromeActivityTestRule; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; + +/** + * View tests for the keyboard accessory tab layout component. + */ +@RunWith(ChromeJUnit4ClassRunner.class) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +public class KeyboardAccessoryTabLayoutViewTest { + private PropertyModel mModel; + private KeyboardAccessoryTabLayoutView mView; + + @Rule + public ChromeActivityTestRule<ChromeTabbedActivity> mActivityTestRule = + new ChromeActivityTestRule<>(ChromeTabbedActivity.class); + + private KeyboardAccessoryData.Tab createTestTab(String contentDescription) { + return new KeyboardAccessoryData.Tab( + mActivityTestRule.getActivity().getResources().getDrawable( + android.R.drawable.ic_lock_lock), // Unused. + contentDescription, + R.layout.empty_accessory_sheet, // Unused. + AccessoryTabType.ALL, + null); // Unused. + } + + /** + * Matches a tab with a given content description. Selecting the content description alone will + * match all icons of the tabs as well. + * @param description The description to look for. + * @return Returns a matcher that can be used in |onView| or within other {@link Matcher}s. + */ + private static Matcher<View> isTabWithDescription(String description) { + return allOf(withContentDescription(description), + instanceOf(ImageView.class)); // Match only the image. + } + + @Before + public void setUp() throws InterruptedException { + mActivityTestRule.startMainActivityOnBlankPage(); + ThreadUtils.runOnUiThreadBlocking(() -> { + mModel = new PropertyModel.Builder(TABS, ACTIVE_TAB, TAB_SELECTION_CALLBACKS) + .with(TABS, new ListModel<>()) + .with(ACTIVE_TAB, null) + .build(); + ViewStub viewStub = + mActivityTestRule.getActivity().findViewById(R.id.keyboard_accessory_stub); + mView = viewStub.inflate().findViewById(R.id.tabs); + KeyboardAccessoryTabLayoutCoordinator.createTabViewBinder(mModel, mView); + }); + } + + @Test + @MediumTest + public void testRemovesTabs() { + ThreadUtils.runOnUiThreadBlocking(() -> { + ((KeyboardAccessoryView) mView.getParent().getParent()).setVisible(true); + mModel.get(TABS).set(new KeyboardAccessoryData.Tab[] {createTestTab("FirstTab"), + createTestTab("SecondTab"), createTestTab("ThirdTab")}); + }); + + onView(isRoot()).check( + (root, e) -> waitForView((ViewGroup) root, isTabWithDescription("FirstTab"))); + onView(isTabWithDescription("FirstTab")).check(matches(isDisplayed())); + onView(isTabWithDescription("SecondTab")).check(matches(isDisplayed())); + onView(isTabWithDescription("ThirdTab")).check(matches(isDisplayed())); + + ThreadUtils.runOnUiThreadBlocking(() -> mModel.get(TABS).remove(mModel.get(TABS).get(1))); + + onView(isRoot()).check( + (root, e) + -> waitForView((ViewGroup) root, isTabWithDescription("SecondTab"), + VIEW_INVISIBLE | VIEW_GONE | VIEW_NULL)); + onView(isTabWithDescription("FirstTab")).check(matches(isDisplayed())); + onView(isTabWithDescription("SecondTab")).check(doesNotExist()); + onView(isTabWithDescription("ThirdTab")).check(matches(isDisplayed())); + } + + @Test + @MediumTest + public void testAddsTabs() { + ThreadUtils.runOnUiThreadBlocking(() -> { + ((KeyboardAccessoryView) mView.getParent().getParent()).setVisible(true); + mModel.get(TABS).set(new KeyboardAccessoryData.Tab[] { + createTestTab("FirstTab"), createTestTab("SecondTab")}); + }); + + onView(isRoot()).check( + (root, e) -> waitForView((ViewGroup) root, isTabWithDescription("FirstTab"))); + onView(isTabWithDescription("FirstTab")).check(matches(isDisplayed())); + onView(isTabWithDescription("SecondTab")).check(matches(isDisplayed())); + onView(isTabWithDescription("ThirdTab")).check(doesNotExist()); + + ThreadUtils.runOnUiThreadBlocking(() -> mModel.get(TABS).add(createTestTab("ThirdTab"))); + + onView(isRoot()).check( + (root, e) -> waitForView((ViewGroup) root, isTabWithDescription("ThirdTab"))); + onView(isTabWithDescription("FirstTab")).check(matches(isDisplayed())); + onView(isTabWithDescription("SecondTab")).check(matches(isDisplayed())); + onView(isTabWithDescription("ThirdTab")).check(matches(isDisplayed())); + } +} \ No newline at end of file
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryViewTest.java index 6b187f5..7493fb0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryViewTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryViewTest.java
@@ -10,11 +10,8 @@ import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.isRoot; -import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription; import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.core.AllOf.allOf; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; @@ -23,10 +20,7 @@ import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessoryAction.AUTOFILL_SUGGESTION; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessoryAction.GENERATE_PASSWORD_AUTOMATIC; import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.ACTIONS; -import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.ACTIVE_TAB; import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.BOTTOM_OFFSET_PX; -import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.TABS; -import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.TAB_SELECTION_CALLBACKS; import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.VISIBLE; import static org.chromium.chrome.test.util.ViewUtils.VIEW_GONE; import static org.chromium.chrome.test.util.ViewUtils.VIEW_INVISIBLE; @@ -37,9 +31,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewStub; -import android.widget.ImageView; -import org.hamcrest.Matcher; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -60,7 +52,6 @@ import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; -import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicReference; /** @@ -77,35 +68,11 @@ public ChromeActivityTestRule<ChromeTabbedActivity> mActivityTestRule = new ChromeActivityTestRule<>(ChromeTabbedActivity.class); - private KeyboardAccessoryData.Tab createTestTab(String contentDescription) { - return new KeyboardAccessoryData.Tab( - mActivityTestRule.getActivity().getResources().getDrawable( - android.R.drawable.ic_lock_lock), // Unused. - contentDescription, - R.layout.empty_accessory_sheet, // Unused. - AccessoryTabType.ALL, - null); // Unused. - } - - /** - * Matches a tab with a given content description. Selecting the content description alone will - * match all icons of the tabs as well. - * @param description The description to look for. - * @return Returns a matcher that can be used in |onView| or within other {@link Matcher}s. - */ - private static Matcher<View> isTabWithDescription(String description) { - return allOf(withContentDescription(description), - instanceOf(ImageView.class)); // Match only the image. - } - @Before public void setUp() throws InterruptedException { mActivityTestRule.startMainActivityOnBlankPage(); ThreadUtils.runOnUiThreadBlocking(() -> { - mModel = new PropertyModel - .Builder(ACTIONS, TABS, VISIBLE, BOTTOM_OFFSET_PX, ACTIVE_TAB, - TAB_SELECTION_CALLBACKS) - .with(TABS, new ListModel<>()) + mModel = new PropertyModel.Builder(ACTIONS, VISIBLE, BOTTOM_OFFSET_PX) .with(ACTIONS, new ListModel<>()) .with(VISIBLE, false) .build(); @@ -123,8 +90,7 @@ @Test @MediumTest - public void testAccessoryVisibilityChangedByModel() - throws ExecutionException, InterruptedException { + public void testAccessoryVisibilityChangedByModel() throws InterruptedException { // Initially, there shouldn't be a view yet. assertNull(mKeyboardAccessoryView.poll()); @@ -211,54 +177,4 @@ onView(withText("Second")).check(doesNotExist()); onView(withText("Third")).check(matches(isDisplayed())); } - - @Test - @MediumTest - public void testRemovesTabs() { - ThreadUtils.runOnUiThreadBlocking(() -> { - mModel.set(VISIBLE, true); - mModel.get(TABS).set(new KeyboardAccessoryData.Tab[] {createTestTab("FirstTab"), - createTestTab("SecondTab"), createTestTab("ThirdTab")}); - }); - - onView(isRoot()).check( - (root, e) -> waitForView((ViewGroup) root, isTabWithDescription("FirstTab"))); - onView(isTabWithDescription("FirstTab")).check(matches(isDisplayed())); - onView(isTabWithDescription("SecondTab")).check(matches(isDisplayed())); - onView(isTabWithDescription("ThirdTab")).check(matches(isDisplayed())); - - ThreadUtils.runOnUiThreadBlocking(() -> mModel.get(TABS).remove(mModel.get(TABS).get(1))); - - onView(isRoot()).check( - (root, e) - -> waitForView((ViewGroup) root, isTabWithDescription("SecondTab"), - VIEW_INVISIBLE | VIEW_GONE | VIEW_NULL)); - onView(isTabWithDescription("FirstTab")).check(matches(isDisplayed())); - onView(isTabWithDescription("SecondTab")).check(doesNotExist()); - onView(isTabWithDescription("ThirdTab")).check(matches(isDisplayed())); - } - - @Test - @MediumTest - public void testAddsTabs() { - ThreadUtils.runOnUiThreadBlocking(() -> { - mModel.set(VISIBLE, true); - mModel.get(TABS).set(new KeyboardAccessoryData.Tab[] { - createTestTab("FirstTab"), createTestTab("SecondTab")}); - }); - - onView(isRoot()).check( - (root, e) -> waitForView((ViewGroup) root, isTabWithDescription("FirstTab"))); - onView(isTabWithDescription("FirstTab")).check(matches(isDisplayed())); - onView(isTabWithDescription("SecondTab")).check(matches(isDisplayed())); - onView(isTabWithDescription("ThirdTab")).check(doesNotExist()); - - ThreadUtils.runOnUiThreadBlocking(() -> mModel.get(TABS).add(createTestTab("ThirdTab"))); - - onView(isRoot()).check( - (root, e) -> waitForView((ViewGroup) root, isTabWithDescription("ThirdTab"))); - onView(isTabWithDescription("FirstTab")).check(matches(isDisplayed())); - onView(isTabWithDescription("SecondTab")).check(matches(isDisplayed())); - onView(isTabWithDescription("ThirdTab")).check(matches(isDisplayed())); - } } \ No newline at end of file
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleUITest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleUITest.java index e1573f0..e0bac5f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleUITest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleUITest.java
@@ -17,7 +17,6 @@ import android.support.test.uiautomator.UiDevice; import android.view.View; import android.view.ViewGroup; -import android.view.ViewGroup.MarginLayoutParams; import org.junit.After; import org.junit.Assert; @@ -456,55 +455,11 @@ CustomTabActivity cctActivity = getActivity(); int defaultHeight = cctActivity.getFullscreenManager().getTopControlsHeight(); int newHeight = defaultHeight + 10; - getModuleCoordinator().setTopBarHeight(newHeight); + cctActivity.getComponent().resolveDynamicModuleCoordinator().setTopBarHeight(newHeight); assertEquals(newHeight, cctActivity.getFullscreenManager().getTopControlsHeight()); }); } - @Test - @SmallTest - @Features.DisableFeatures(ChromeFeatureList.CCT_MODULE_CUSTOM_HEADER) - public void testSetTopBarContentView_featureDisabled_progressBarNoChange() throws Exception { - Intent intent = new IntentBuilder(mModuleManagedPage) - .setModuleHostList(getServerHostsList()) - .setModuleManagedUrlRegex(getModuleManagedRegex()) - .setHideCCTHeader(true) - .build(); - mActivityRule.startCustomTabActivityWithIntent(intent); - - runOnUiThread(() -> Assert.assertFalse(canChangeProgressBarTopMargin())); - } - - @Test - @SmallTest - @Features. - EnableFeatures({ChromeFeatureList.CCT_MODULE, ChromeFeatureList.CCT_MODULE_CUSTOM_HEADER}) - public void testSetTopBarContentView_cctHeaderNotHidden_progressBarNoChange() throws Exception { - Intent intent = new IntentBuilder(mModuleManagedPage) - .setModuleHostList(getServerHostsList()) - .setModuleManagedUrlRegex(getModuleManagedRegex()) - .setHideCCTHeader(false) - .build(); - mActivityRule.startCustomTabActivityWithIntent(intent); - - runOnUiThread(() -> Assert.assertFalse(canChangeProgressBarTopMargin())); - } - - @Test - @SmallTest - @Features. - EnableFeatures({ChromeFeatureList.CCT_MODULE, ChromeFeatureList.CCT_MODULE_CUSTOM_HEADER}) - public void testSetTopBarContentView_withModuleAndExtras_progressBarChanged() throws Exception { - Intent intent = new IntentBuilder(mModuleManagedPage) - .setModuleHostList(getServerHostsList()) - .setModuleManagedUrlRegex(getModuleManagedRegex()) - .setHideCCTHeader(true) - .build(); - mActivityRule.startCustomTabActivityWithIntent(intent); - - runOnUiThread(() -> Assert.assertTrue(canChangeProgressBarTopMargin())); - } - private void assertNoTopBar() { runOnUiThread(() -> { ViewGroup topBar = getActivity().findViewById(R.id.topbar); @@ -566,36 +521,4 @@ private DynamicModuleCoordinator getModuleCoordinator() { return getActivity().getComponent().resolveDynamicModuleCoordinator(); } - - private boolean canChangeProgressBarTopMargin() { - CustomTabActivity cctActivity = getActivity(); - ViewGroup controlContainerView = cctActivity.findViewById(R.id.control_container); - int progressBarHeight = 0; - for (int index = 0; index < controlContainerView.getChildCount(); index++) { - View childView = controlContainerView.getChildAt(index); - if (childView.getId() != R.id.toolbar_container) { - // Either ToolbarProgressBar or ToolbarProgressBarAnimatingView - progressBarHeight = childView.getHeight(); - break; - } - } - Assert.assertNotEquals(progressBarHeight, 0); - - View anyView = new View(cctActivity); - getModuleCoordinator().setTopBarContentView(anyView); - int newMargin = anyView.getBottom() - progressBarHeight; - - boolean canChange = false; - for (int index = 0; index < controlContainerView.getChildCount(); index++) { - View childView = controlContainerView.getChildAt(index); - if (childView.getId() != R.id.toolbar_container) { - if (((MarginLayoutParams) childView.getLayoutParams()).topMargin != newMargin) { - return false; - } else { - canChange = true; - } - } - } - return canChange; - } } \ 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 c18afee0..54379a47f 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
@@ -7,18 +7,15 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessoryAction.AUTOFILL_SUGGESTION; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessoryAction.GENERATE_PASSWORD_AUTOMATIC; import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.ACTIONS; -import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.ACTIVE_TAB; -import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.TABS; import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.VISIBLE; import org.junit.Before; @@ -53,13 +50,13 @@ @Mock private PropertyObserver<PropertyKey> mMockPropertyObserver; @Mock - private ListObservable.ListObserver<Void> mMockTabListObserver; - @Mock private ListObservable.ListObserver<Void> mMockActionListObserver; @Mock private KeyboardAccessoryCoordinator.VisibilityDelegate mMockVisibilityDelegate; @Mock private KeyboardAccessoryModernView mMockView; + @Mock + private KeyboardAccessoryTabLayoutView mMockTabSwitcherView; private final KeyboardAccessoryData.Tab mTestTab = new KeyboardAccessoryData.Tab(null, null, 0, 0, null); @@ -76,6 +73,7 @@ features.put(ChromeFeatureList.AUTOFILL_KEYBOARD_ACCESSORY, true); ChromeFeatureList.setTestFeatures(features); + when(mMockView.getTabLayout()).thenReturn(mMockTabSwitcherView); mCoordinator = new KeyboardAccessoryCoordinator( mMockVisibilityDelegate, new FakeViewProvider<>(mMockView)); mMediator = mCoordinator.getMediatorForTesting(); @@ -106,22 +104,6 @@ } @Test - public void testChangingTabsNotifiesTabObserver() { - mModel.get(TABS).addObserver(mMockTabListObserver); - - // Calling addTab on the coordinator should make model propagate that it has a new tab. - mCoordinator.addTab(mTestTab); - verify(mMockTabListObserver).onItemRangeInserted(mModel.get(TABS), 0, 1); - assertThat(mModel.get(TABS).size(), is(1)); - assertThat(mModel.get(TABS).get(0), is(mTestTab)); - - // Calling hide on the coordinator should make model propagate that it's invisible. - mCoordinator.removeTab(mTestTab); - verify(mMockTabListObserver).onItemRangeRemoved(mModel.get(TABS), 0, 1); - assertThat(mModel.get(TABS).size(), is(0)); - } - - @Test public void testModelNotifiesAboutActionsChangedByProvider() { mModel.get(ACTIONS).addObserver(mMockActionListObserver); @@ -170,24 +152,6 @@ } @Test - public void testModelDoesntNotifyUnchangedActiveTab() { - mModel.addObserver(mMockPropertyObserver); - - assertThat(mModel.get(ACTIVE_TAB), is(nullValue())); - mModel.set(ACTIVE_TAB, null); - assertThat(mModel.get(ACTIVE_TAB), is(nullValue())); - verify(mMockPropertyObserver, never()).onPropertyChanged(mModel, ACTIVE_TAB); - - mModel.set(ACTIVE_TAB, 0); - assertThat(mModel.get(ACTIVE_TAB), is(0)); - verify(mMockPropertyObserver).onPropertyChanged(mModel, ACTIVE_TAB); - - mModel.set(ACTIVE_TAB, 0); - assertThat(mModel.get(ACTIVE_TAB), is(0)); - verify(mMockPropertyObserver).onPropertyChanged(mModel, ACTIVE_TAB); - } - - @Test public void testIsVisibleWithSuggestionsBeforeKeyboardComesUp() { KeyboardAccessoryData.PropertyProvider<Action[]> autofillSuggestionProvider = new KeyboardAccessoryData.PropertyProvider<>(AUTOFILL_SUGGESTION); @@ -319,28 +283,6 @@ } @Test - public void testClosingTabDismissesOpenSheet() { - mModel.set(ACTIVE_TAB, 0); - mModel.addObserver(mMockPropertyObserver); - assertThat(mModel.get(ACTIVE_TAB), is(0)); - - // Closing the active tab should reset the tab which should trigger the visibility delegate. - mCoordinator.closeActiveTab(); - assertThat(mModel.get(ACTIVE_TAB), is(nullValue())); - verify(mMockPropertyObserver).onPropertyChanged(mModel, ACTIVE_TAB); - verify(mMockVisibilityDelegate).onCloseAccessorySheet(); - } - - @Test - public void testClosingTabIsNoOpForAlreadyClosedTab() { - mModel.set(ACTIVE_TAB, null); - mModel.addObserver(mMockPropertyObserver); - - mCoordinator.closeActiveTab(); - verifyNoMoreInteractions(mMockPropertyObserver, mMockVisibilityDelegate); - } - - @Test public void testRecordsOneImpressionForEveryInitialContentOnVisibilityChange() { assertThat(RecordHistogram.getHistogramTotalCountForTesting( KeyboardAccessoryMetricsRecorder.UMA_KEYBOARD_ACCESSORY_BAR_SHOWN),
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutControllerTest.java new file mode 100644 index 0000000..4008b14 --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutControllerTest.java
@@ -0,0 +1,137 @@ +// 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 static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryTabLayoutProperties.ACTIVE_TAB; +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryTabLayoutProperties.TABS; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; + +import org.chromium.base.metrics.test.ShadowRecordHistogram; +import org.chromium.base.task.test.CustomShadowAsyncTask; +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.modelutil.ListObservable; +import org.chromium.chrome.browser.modelutil.PropertyKey; +import org.chromium.chrome.browser.modelutil.PropertyModel; +import org.chromium.chrome.browser.modelutil.PropertyObservable.PropertyObserver; + +import java.util.HashMap; + +/** + * Controller tests for the keyboard accessory tab layout component. + */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE, + shadows = {CustomShadowAsyncTask.class, ShadowRecordHistogram.class}) +public class KeyboardAccessoryTabLayoutControllerTest { + @Mock + private PropertyObserver<PropertyKey> mMockPropertyObserver; + @Mock + private ListObservable.ListObserver<Void> mMockTabListObserver; + @Mock + private KeyboardAccessoryTabLayoutCoordinator.AccessoryTabObserver mMockAccessoryTabObserver; + @Mock + private KeyboardAccessoryTabLayoutView mMockView; + + private final KeyboardAccessoryData.Tab mTestTab = + new KeyboardAccessoryData.Tab(null, null, 0, 0, null); + + private KeyboardAccessoryTabLayoutCoordinator mCoordinator; + private PropertyModel mModel; + private KeyboardAccessoryTabLayoutMediator mMediator; + + @Before + public void setUp() { + ShadowRecordHistogram.reset(); + MockitoAnnotations.initMocks(this); + HashMap<String, Boolean> features = new HashMap<>(); + features.put(ChromeFeatureList.AUTOFILL_KEYBOARD_ACCESSORY, true); + ChromeFeatureList.setTestFeatures(features); + + mCoordinator = new KeyboardAccessoryTabLayoutCoordinator(); + mMediator = mCoordinator.getMediatorForTesting(); + mModel = mCoordinator.getModelForTesting(); + mCoordinator.assignNewView(mMockView); + mCoordinator.setTabObserver(mMockAccessoryTabObserver); + } + + @Test + public void testCreatesValidSubComponents() { + assertThat(mCoordinator, is(notNullValue())); + assertThat(mMediator, is(notNullValue())); + assertThat(mModel, is(notNullValue())); + } + + @Test + public void testChangingTabsNotifiesTabObserver() { + mModel.get(TABS).addObserver(mMockTabListObserver); + + // Calling addTab on the coordinator should make the model propagate that it has a new tab. + mCoordinator.getTabSwitchingDelegate().addTab(mTestTab); + verify(mMockTabListObserver).onItemRangeInserted(mModel.get(TABS), 0, 1); + assertThat(mModel.get(TABS).size(), is(1)); + assertThat(mModel.get(TABS).get(0), is(mTestTab)); + + // Calling hide on the coordinator should make the model propagate that it's invisible. + mCoordinator.getTabSwitchingDelegate().removeTab(mTestTab); + verify(mMockTabListObserver).onItemRangeRemoved(mModel.get(TABS), 0, 1); + assertThat(mModel.get(TABS).size(), is(0)); + } + + @Test + public void testModelDoesntNotifyUnchangedActiveTab() { + mModel.addObserver(mMockPropertyObserver); + + assertThat(mModel.get(ACTIVE_TAB), is(nullValue())); + mModel.set(ACTIVE_TAB, null); + assertThat(mModel.get(ACTIVE_TAB), is(nullValue())); + verify(mMockPropertyObserver, never()).onPropertyChanged(mModel, ACTIVE_TAB); + + mModel.set(ACTIVE_TAB, 0); + assertThat(mModel.get(ACTIVE_TAB), is(0)); + verify(mMockPropertyObserver).onPropertyChanged(mModel, ACTIVE_TAB); + + mModel.set(ACTIVE_TAB, 0); + assertThat(mModel.get(ACTIVE_TAB), is(0)); + verify(mMockPropertyObserver).onPropertyChanged(mModel, ACTIVE_TAB); + } + + @Test + public void testClosingTabDismissesOpenSheet() { + mModel.set(ACTIVE_TAB, 0); + mModel.addObserver(mMockPropertyObserver); + assertThat(mModel.get(ACTIVE_TAB), is(0)); + + // Closing the active tab should reset the tab which should trigger the visibility delegate. + mCoordinator.getTabSwitchingDelegate().closeActiveTab(); + assertThat(mModel.get(ACTIVE_TAB), is(nullValue())); + verify(mMockPropertyObserver).onPropertyChanged(mModel, ACTIVE_TAB); + verify(mMockAccessoryTabObserver).onActiveTabChanged(null); + } + + @Test + public void testClosingTabIsNoOpForAlreadyClosedTab() { + mModel.set(ACTIVE_TAB, null); + mModel.addObserver(mMockPropertyObserver); + + mCoordinator.getTabSwitchingDelegate().closeActiveTab(); + verifyNoMoreInteractions( + mMockPropertyObserver, mMockTabListObserver, mMockAccessoryTabObserver); + } +}
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 d28892a..de23ea44 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
@@ -20,8 +20,8 @@ import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessoryAction.GENERATE_PASSWORD_AUTOMATIC; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetTabModel.AccessorySheetDataPiece.Type.PASSWORD_INFO; import static org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetTabModel.AccessorySheetDataPiece.getType; -import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.ACTIVE_TAB; -import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryProperties.TABS; +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryTabLayoutProperties.ACTIVE_TAB; +import static org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryTabLayoutProperties.TABS; import static org.chromium.chrome.browser.tab.Tab.INVALID_TAB_ID; import static org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType.FROM_BROWSER_ACTIONS; import static org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType.FROM_CLOSE; @@ -90,6 +90,8 @@ @Mock private KeyboardAccessoryModernView mMockKeyboardAccessoryView; @Mock + private KeyboardAccessoryTabLayoutView mMockTabSwitcherView; + @Mock private AccessorySheetView mMockViewPager; @Mock private ListObservable.ListObserver<Void> mMockTabListObserver; @@ -125,6 +127,7 @@ when(mMockActivity.findViewById(android.R.id.content)).thenReturn(mMockContentView); when(mMockResources.getDimensionPixelSize(anyInt())).thenReturn(48); PasswordAccessorySheetCoordinator.IconProvider.getInstance().setIconForTesting(mMockIcon); + when(mMockKeyboardAccessoryView.getTabLayout()).thenReturn(mMockTabSwitcherView); mController.initialize(mMockWindow, new FakeViewProvider<>(mMockKeyboardAccessoryView), new FakeViewProvider<>(mMockViewPager)); @@ -139,29 +142,31 @@ assertThat(mController.getMediatorForTesting().getAccessorySheet(), is(notNullValue())); } + private KeyboardAccessoryTabLayoutCoordinator getTabLayout() { + assert mController.getKeyboardAccessory() != null; + return mController.getKeyboardAccessory().getTabLayoutForTesting(); + } + @Test public void testAddingNewTabIsAddedToAccessoryAndSheet() { - PropertyModel keyboardAccessoryModel = - mController.getKeyboardAccessory().getMediatorForTesting().getModelForTesting(); - keyboardAccessoryModel.get(KeyboardAccessoryProperties.TABS) - .addObserver(mMockTabListObserver); - PropertyModel accessorySheetModel = mController.getMediatorForTesting() .getAccessorySheet() .getMediatorForTesting() .getModelForTesting(); accessorySheetModel.get(AccessorySheetProperties.TABS).addObserver(mMockTabListObserver); + getTabLayout().getModelForTesting().get(TABS).addObserver(mMockTabListObserver); - assertThat(keyboardAccessoryModel.get(KeyboardAccessoryProperties.TABS).size(), is(0)); + assertThat(getTabLayout().getModelForTesting().get(TABS).size(), is(0)); + assertThat(accessorySheetModel.get(AccessorySheetProperties.TABS).size(), is(0)); + mController.getMediatorForTesting().addTab( new KeyboardAccessoryData.Tab(null, null, 0, 0, null)); verify(mMockTabListObserver) - .onItemRangeInserted( - keyboardAccessoryModel.get(KeyboardAccessoryProperties.TABS), 0, 1); + .onItemRangeInserted(getTabLayout().getModelForTesting().get(TABS), 0, 1); verify(mMockTabListObserver) .onItemRangeInserted(accessorySheetModel.get(AccessorySheetProperties.TABS), 0, 1); - assertThat(keyboardAccessoryModel.get(KeyboardAccessoryProperties.TABS).size(), is(1)); + assertThat(getTabLayout().getModelForTesting().get(TABS).size(), is(1)); assertThat(accessorySheetModel.get(AccessorySheetProperties.TABS).size(), is(1)); } @@ -230,7 +235,7 @@ firstTabProvider.notifyObservers(new Action[] { new Action("Generate Password", GENERATE_PASSWORD_AUTOMATIC, p -> {})}); mMockItemListObserver.onItemRangeInserted(keyboardActions, 0, 1); - assertThat(keyboardActions.get(0).getCaption(), is("Generate Password")); + assertThat(getFirstKeyboardActionTitle(), is("Generate Password")); // Simulate creating a second tab: Tab secondTab = addTab(mediator, 2222, firstTab); @@ -242,7 +247,7 @@ // Simulate switching back to the first tab: switchTab(mediator, /*from=*/secondTab, /*to=*/firstTab); mMockItemListObserver.onItemRangeInserted(keyboardActions, 0, 1); - assertThat(keyboardActions.get(0).getCaption(), is("Generate Password")); + assertThat(getFirstKeyboardActionTitle(), is("Generate Password")); // And back to the second: switchTab(mediator, /*from=*/firstTab, /*to=*/secondTab); @@ -253,68 +258,64 @@ @Test public void testPasswordTabRestoredWhenSwitchingBrowserTabs() { ManualFillingMediator mediator = mController.getMediatorForTesting(); - PropertyModel keyboardAccessoryModel = - mediator.getKeyboardAccessory().getMediatorForTesting().getModelForTesting(); PropertyModel accessorySheetModel = mediator.getAccessorySheet().getMediatorForTesting().getModelForTesting(); - assertThat(keyboardAccessoryModel.get(KeyboardAccessoryProperties.TABS).size(), is(0)); + assertThat(getTabLayout().getModelForTesting().get(TABS).size(), is(0)); assertThat(accessorySheetModel.get(AccessorySheetProperties.TABS).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.get(KeyboardAccessoryProperties.TABS).size(), is(1)); + assertThat(getTabLayout().getModelForTesting().get(TABS).size(), is(1)); assertThat(accessorySheetModel.get(AccessorySheetProperties.TABS).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.get(KeyboardAccessoryProperties.TABS).size(), is(0)); + assertThat(getTabLayout().getModelForTesting().get(TABS).size(), is(0)); assertThat(accessorySheetModel.get(AccessorySheetProperties.TABS).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.get(KeyboardAccessoryProperties.TABS).size(), is(1)); + assertThat(getTabLayout().getModelForTesting().get(TABS).size(), is(1)); assertThat(accessorySheetModel.get(AccessorySheetProperties.TABS).size(), is(1)); // And back to the second: switchTab(mediator, /*from=*/firstTab, /*to=*/secondTab); // Still no tab in accessory and sheet: - assertThat(keyboardAccessoryModel.get(KeyboardAccessoryProperties.TABS).size(), is(0)); + assertThat(getTabLayout().getModelForTesting().get(TABS).size(), is(0)); assertThat(accessorySheetModel.get(AccessorySheetProperties.TABS).size(), is(0)); } @Test public void testPasswordTabRestoredWhenClosingTabIsUndone() { ManualFillingMediator mediator = mController.getMediatorForTesting(); - PropertyModel keyboardAccessoryModel = - mediator.getKeyboardAccessory().getMediatorForTesting().getModelForTesting(); - assertThat(keyboardAccessoryModel.get(TABS).size(), is(0)); + assertThat(getTabLayout().getModelForTesting().get(TABS).size(), is(0)); // Create a new tab with a passwords tab: Tab tab = addTab(mediator, 1111, null); mController.registerPasswordProvider(new PropertyProvider<>()); - assertThat(keyboardAccessoryModel.get(TABS).size(), is(1)); + assertThat(getTabLayout().getModelForTesting().get(TABS).size(), is(1)); // Simulate closing the tab: mediator.getTabModelObserverForTesting().willCloseTab(tab, false); mediator.getTabObserverForTesting().onHidden(tab, TabHidingType.CHANGED_TABS); // Temporary removes the tab, but keeps it in memory so it can be brought back on undo: - assertThat(keyboardAccessoryModel.get(TABS).size(), is(0)); + assertThat(getTabLayout().getModelForTesting().get(TABS).size(), is(0)); // Simulate undo closing the tab and selecting it: mediator.getTabModelObserverForTesting().tabClosureUndone(tab); switchTab(mediator, null, tab); // There should still be a tab in the accessory: - assertThat(keyboardAccessoryModel.get(TABS).size(), is(1)); + assertThat(getTabLayout().getModelForTesting().get(TABS).size(), is(1)); // Simulate closing the tab and committing to it (i.e. wait out undo message): closeTab(mediator, tab, null); mediator.getTabModelObserverForTesting().tabClosureCommitted(tab); - assertThat(keyboardAccessoryModel.get(TABS).size(), is(0)); + assertThat(getTabLayout().getModelForTesting().get(TABS).size(), is(0)); } @Test @@ -382,16 +383,12 @@ // The current tab should not be influenced by the delayed provider. assertThat(keyboardAccessoryModel.get(KeyboardAccessoryProperties.ACTIONS).size(), is(1)); - assertThat( - keyboardAccessoryModel.get(KeyboardAccessoryProperties.ACTIONS).get(0).getCaption(), - is("Test Action")); + assertThat(getFirstKeyboardActionTitle(), is("Test Action")); // Switching tabs back should only show the action that was received in the background. switchTab(mediator, secondTab, tab); assertThat(keyboardAccessoryModel.get(KeyboardAccessoryProperties.ACTIONS).size(), is(1)); - assertThat( - keyboardAccessoryModel.get(KeyboardAccessoryProperties.ACTIONS).get(0).getCaption(), - is("Delayed")); + assertThat(getFirstKeyboardActionTitle(), is("Delayed")); } @Test @@ -428,23 +425,19 @@ new Action[] {new Action("2BKept", GENERATE_PASSWORD_AUTOMATIC, (action) -> {})}); // The current tab should be valid. - assertThat(keyboardAccessoryModel.get(KeyboardAccessoryProperties.TABS).size(), is(1)); + assertThat(getTabLayout().getModelForTesting().get(TABS).size(), is(1)); assertThat(accessorySheetModel.get(AccessorySheetProperties.TABS).size(), is(1)); assertThat(keyboardAccessoryModel.get(KeyboardAccessoryProperties.ACTIONS).size(), is(1)); - assertThat( - keyboardAccessoryModel.get(KeyboardAccessoryProperties.ACTIONS).get(0).getCaption(), - is("2BKept")); + assertThat(getFirstKeyboardActionTitle(), is("2BKept")); // Request destruction of the first Tab: mediator.getTabObserverForTesting().onDestroyed(firstTab); // The current tab should not be influenced by the destruction. - assertThat(keyboardAccessoryModel.get(KeyboardAccessoryProperties.TABS).size(), is(1)); + assertThat(getTabLayout().getModelForTesting().get(TABS).size(), is(1)); assertThat(accessorySheetModel.get(AccessorySheetProperties.TABS).size(), is(1)); assertThat(keyboardAccessoryModel.get(KeyboardAccessoryProperties.ACTIONS).size(), is(1)); - assertThat( - keyboardAccessoryModel.get(KeyboardAccessoryProperties.ACTIONS).get(0).getCaption(), - is("2BKept")); + assertThat(getFirstKeyboardActionTitle(), is("2BKept")); // The other tabs data should be gone. ManualFillingMediator.AccessoryState oldState = mediator.getModelForTesting().get(firstTab); @@ -463,7 +456,7 @@ ManualFillingMediator mediator = mController.getMediatorForTesting(); // Show the accessory bar to make sure it would be dismissed. - mediator.getKeyboardAccessory().addTab( + getTabLayout().getTabSwitchingDelegate().addTab( new KeyboardAccessoryData.Tab(null, null, 0, 0, null)); mediator.getKeyboardAccessory().requestShowing(); assertThat(mediator.getKeyboardAccessory().isShown(), is(true)); @@ -483,7 +476,7 @@ when(mMockKeyboard.isSoftKeyboardShowing(eq(mMockActivity), any())).thenReturn(true); // Show the accessory bar for the default dimensions (300x80@2.f). - mediator.getKeyboardAccessory().addTab( + getTabLayout().getTabSwitchingDelegate().addTab( new KeyboardAccessoryData.Tab(null, null, 0, 0, null)); mediator.showWhenKeyboardIsVisible(); assertThat(mediator.getKeyboardAccessory().isShown(), is(true)); @@ -530,7 +523,7 @@ // As soon as active tab and keyboard change, |isFillingViewShown| returns the expected // state - even if the sheet component wasn't updated yet. - accessory.getMediatorForTesting().getModelForTesting().set(ACTIVE_TAB, 0); + getTabLayout().getModelForTesting().set(ACTIVE_TAB, 0); when(mMockKeyboard.isSoftKeyboardShowing(eq(mMockActivity), any())).thenReturn(false); assertThat(mController.isFillingViewShown(null), is(true)); @@ -655,4 +648,14 @@ assert info.getFields().size() > 1; return info.getFields().get(1).getDisplayText(); } + + private String getFirstKeyboardActionTitle() { + return mController.getMediatorForTesting() + .getKeyboardAccessory() + .getMediatorForTesting() + .getModelForTesting() + .get(KeyboardAccessoryProperties.ACTIONS) + .get(0) + .getCaption(); + } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/usage_stats/PageViewObserverTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/usage_stats/PageViewObserverTest.java new file mode 100644 index 0000000..80631a5 --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/usage_stats/PageViewObserverTest.java
@@ -0,0 +1,245 @@ +// 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.usage_stats; + +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.app.Activity; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatcher; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.Tab.TabHidingType; +import org.chromium.chrome.browser.tab.TabObserver; +import org.chromium.chrome.browser.tabmodel.TabModel; +import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; +import org.chromium.chrome.browser.tabmodel.TabModelObserver; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; + +import java.util.Arrays; + +/** Unit tests for PageViewObserver. */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public final class PageViewObserverTest { + private static final String STARTING_URL = "http://starting.url"; + private static final String DIFFERENT_URL = "http://different.url"; + private static final String STARTING_FQDN = "starting.url"; + private static final String DIFFERENT_FQDN = "different.url"; + + @Mock + private Activity mActivity; + @Mock + private TabModelSelector mTabModelSelector; + @Mock + private TabModel mTabModel; + @Mock + private Tab mTab; + @Mock + private Tab mTab2; + @Mock + private EventTracker mEventTracker; + @Captor + private ArgumentCaptor<TabObserver> mTabObserverCaptor; + @Captor + private ArgumentCaptor<TabModelObserver> mTabModelObserverCaptor; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + doReturn(false).when(mTab).isIncognito(); + doReturn(null).when(mTab).getUrl(); + doReturn(Arrays.asList(mTabModel)).when(mTabModelSelector).getModels(); + doReturn(mTab).when(mTabModelSelector).getCurrentTab(); + } + + @Test + public void createPageViewTimer_withNoTab_noCrash() { + doReturn(null).when(mTabModelSelector).getCurrentTab(); + PageViewObserver observer = createPageViewObserver(); + } + + @Test + public void onUpdateUrl_currentlyNull_startReported() { + PageViewObserver observer = createPageViewObserver(); + onUpdateUrl(mTab, STARTING_URL); + verify(mEventTracker, times(1)).addWebsiteEvent(argThat(isStartEvent(STARTING_FQDN))); + } + + @Test + public void onUpdateUrl_nullUrl() { + PageViewObserver observer = createPageViewObserver(); + onUpdateUrl(mTab, null); + onHidden(mTab, TabHidingType.ACTIVITY_HIDDEN); + verify(mEventTracker, times(0)).addWebsiteEvent(any()); + } + + @Test + public void onUpdateUrl_startStopReported() { + PageViewObserver observer = createPageViewObserver(); + onUpdateUrl(mTab, STARTING_URL); + verify(mEventTracker, times(1)).addWebsiteEvent(argThat(isStartEvent(STARTING_FQDN))); + reset(mEventTracker); + onUpdateUrl(mTab, DIFFERENT_URL); + verify(mEventTracker, times(1)).addWebsiteEvent(argThat(isStartEvent(DIFFERENT_FQDN))); + verify(mEventTracker, times(1)).addWebsiteEvent(argThat(isStopEvent(STARTING_FQDN))); + } + + @Test + public void onUpdateUrl_sameDomain_startStopNotReported() { + PageViewObserver observer = createPageViewObserver(); + onUpdateUrl(mTab, STARTING_URL); + verify(mEventTracker, times(1)).addWebsiteEvent(argThat(isStartEvent(STARTING_FQDN))); + onUpdateUrl(mTab, STARTING_URL + "/some_other_page.html"); + verify(mEventTracker, times(1)).addWebsiteEvent(argThat(isStartEvent(STARTING_FQDN))); + } + + @Test + public void switchTabs_startStopReported() { + PageViewObserver observer = createPageViewObserver(); + onUpdateUrl(mTab, STARTING_URL); + reset(mEventTracker); + + doReturn(DIFFERENT_URL).when(mTab2).getUrl(); + didSelectTab(mTab2, TabSelectionType.FROM_USER); + verify(mEventTracker, times(1)).addWebsiteEvent(argThat(isStartEvent(DIFFERENT_FQDN))); + verify(mEventTracker, times(1)).addWebsiteEvent(argThat(isStopEvent(STARTING_FQDN))); + } + + @Test + public void switchTabs_sameDomain_startStopNotReported() { + PageViewObserver observer = createPageViewObserver(); + onUpdateUrl(mTab, STARTING_URL); + verify(mEventTracker, times(1)).addWebsiteEvent(argThat(isStartEvent(STARTING_FQDN))); + + doReturn(STARTING_URL).when(mTab2).getUrl(); + didSelectTab(mTab2, TabSelectionType.FROM_USER); + verify(mEventTracker, times(1)).addWebsiteEvent(argThat(isStartEvent(STARTING_FQDN))); + } + + @Test + public void tabHidden_stopReported() { + PageViewObserver observer = createPageViewObserver(); + onUpdateUrl(mTab, STARTING_URL); + onHidden(mTab, TabHidingType.ACTIVITY_HIDDEN); + + verify(mEventTracker, times(1)).addWebsiteEvent(argThat(isStartEvent(STARTING_FQDN))); + verify(mEventTracker, times(1)).addWebsiteEvent(argThat(isStopEvent(STARTING_FQDN))); + } + + @Test + public void tabShown_startReported() { + PageViewObserver observer = createPageViewObserver(); + doReturn(STARTING_URL).when(mTab).getUrl(); + onShown(mTab, TabSelectionType.FROM_USER); + + verify(mEventTracker, times(1)).addWebsiteEvent(argThat(isStartEvent(STARTING_FQDN))); + } + + @Test + public void tabClosed_switchToNew_startStopReported() { + PageViewObserver observer = createPageViewObserver(); + onUpdateUrl(mTab, STARTING_URL); + onHidden(mTab, TabHidingType.ACTIVITY_HIDDEN); + + doReturn(DIFFERENT_URL).when(mTab2).getUrl(); + onShown(mTab2, TabSelectionType.FROM_CLOSE); + + verify(mEventTracker, times(1)).addWebsiteEvent(argThat(isStartEvent(STARTING_FQDN))); + verify(mEventTracker, times(1)).addWebsiteEvent(argThat(isStopEvent(STARTING_FQDN))); + verify(mEventTracker, times(1)).addWebsiteEvent(argThat(isStartEvent(DIFFERENT_FQDN))); + } + + @Test + public void tabClosed_inBackground_stopNotReported() { + PageViewObserver observer = createPageViewObserver(); + onUpdateUrl(mTab, STARTING_URL); + getTabModelObserver().willCloseTab(mTab2, true); + getTabModelObserver().tabRemoved(mTab2); + + verify(mEventTracker, times(1)).addWebsiteEvent(argThat(isStartEvent(STARTING_FQDN))); + verify(mEventTracker, times(0)).addWebsiteEvent(argThat(isStopEvent(DIFFERENT_FQDN))); + } + + private PageViewObserver createPageViewObserver() { + PageViewObserver observer = + new PageViewObserver(mActivity, mTabModelSelector, mEventTracker); + verify(mTabModel, times(1)).addObserver(mTabModelObserverCaptor.capture()); + if (mTabModelSelector.getCurrentTab() != null) { + verify(mTabModelSelector.getCurrentTab(), times(1)) + .addObserver(mTabObserverCaptor.capture()); + } + return observer; + } + + private void onUpdateUrl(Tab tab, String url) { + getTabObserver().onUpdateUrl(tab, url); + } + + private void onHidden(Tab tab, @TabHidingType int hidingType) { + getTabObserver().onHidden(tab, hidingType); + } + + private void onShown(Tab tab, @TabSelectionType int selectionType) { + getTabObserver().onShown(tab, selectionType); + } + + private void didSelectTab(Tab tab, @TabSelectionType int selectionType) { + getTabModelObserver().didSelectTab(tab, selectionType, 0); + } + + private TabObserver getTabObserver() { + return mTabObserverCaptor.getValue(); + } + + private TabModelObserver getTabModelObserver() { + return mTabModelObserverCaptor.getValue(); + } + + private ArgumentMatcher<WebsiteEvent> isStartEvent(String fqdn) { + return new ArgumentMatcher<WebsiteEvent>() { + @Override + public boolean matches(WebsiteEvent event) { + return event.getType() == WebsiteEvent.EventType.START + && event.getFqdn().equals(fqdn); + } + + @Override + public String toString() { + return "Start event with fqdn: " + fqdn; + } + }; + } + + private ArgumentMatcher<WebsiteEvent> isStopEvent(String fqdn) { + return new ArgumentMatcher<WebsiteEvent>() { + @Override + public boolean matches(WebsiteEvent event) { + return event.getType() == WebsiteEvent.EventType.STOP + && event.getFqdn().equals(fqdn); + } + + @Override + public String toString() { + return "Stop event with fqdn: " + fqdn; + } + }; + } +} \ No newline at end of file
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 9d69c6a..137f4e6 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-73.0.3645.0_rc-r1.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-73.0.3646.0_rc-r1.afdo.bz2 \ No newline at end of file
diff --git a/chrome/app/md_extensions_strings.grdp b/chrome/app/md_extensions_strings.grdp index 5585d4a..da49544 100644 --- a/chrome/app/md_extensions_strings.grdp +++ b/chrome/app/md_extensions_strings.grdp
@@ -124,6 +124,9 @@ <message name="IDS_MD_EXTENSIONS_ACTIVITY_LOG_PAGE_HEADING" desc="The heading of the page displaying an extension's activity log."> Activity Log </message> + <message name="IDS_MD_EXTENSIONS_ACTIVITY_LOG_SEARCH_LABEL" desc="The placeholder label to display in the search bar for the activity log page."> + Search activities + </message> <message name="IDS_MD_EXTENSIONS_ITEM_ID" desc="The text for the label next to the extension id."> <span>ID: </span><ph name="EXTENSION_ID">$1<ex>cfhdojbkjhnklbpkdaibdccddilifddb</ex></ph> </message>
diff --git a/chrome/app/resources/generated_resources_am.xtb b/chrome/app/resources/generated_resources_am.xtb index 4d337bad..50b8eb7 100644 --- a/chrome/app/resources/generated_resources_am.xtb +++ b/chrome/app/resources/generated_resources_am.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">ለመዝለል ESCAPEን ይጫኑ (ይፋዊ ላልሆኑ ግንባታዎች ብቻ)።</translation> <translation id="1093457606523402488">የሚታዩ አውታረ መረቦች፦</translation> <translation id="1094607894174825014">በሚከተለው ላይ የማንብብ ወይም የመጻፍ ክወና ልክ ባልሆነ ማሸጋሸጊያ ነው የተጠየቀው፦ «<ph name="DEVICE_NAME" />»።</translation> -<translation id="109758035718544977">የጣቢያዎች ድምፀ-ከል አንሳ</translation> <translation id="1097658378307015415">ከመግባትዎ በፊት አውታረ መረብ <ph name="NETWORK_ID" />ን ለማንቃት እባክዎ እንደ እንግዳ ይግቡ</translation> <translation id="1103523840287552314">ሁልጊዜ <ph name="LANGUAGE" />ን መተርጎም</translation> <translation id="1108600514891325577">&አቁም</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">ማንነት በማያሳውቅ መስኮት አማካኝነት የአሰሳ ታሪክዎን ሳያስቀምጡ ድሩን ይጠቀሙ</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> የጣት አሻራዎች ተቀናብረዋል</translation> <translation id="1215411991991485844">አዲስ የጀርባ መተግበሪያ ታክሏል</translation> -<translation id="1216654534877302979">ጣቢያዎች ላይ ድምፀ-ከል አድርግ</translation> <translation id="1216659994753476700">እናዝናለን። መገለጫዎን ልንደርስበት አልቻልንም። በዚህ መሣሪያ ላይ የተከማቹ ፋይሎች እና ውሂብ ጠፍተው ሊሆኑ ይችላሉ።<ph name="BR" /> <ph name="BR" /> መገለጫዎን እንደገና ማዋቀር ይኖርብዎታል።<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">ውሂብ በእርስዎ Google Drive መለያ ላይ ያከማቹ</translation> <translation id="1288037062697528143">ፀሐይ ስትጠልቅ የማታ ብርሃን በራስ-ሰር ይበራል</translation> <translation id="1288300545283011870">የንግግር ባህሪያትን</translation> -<translation id="1293177648337752319">የጣቢያን ድምፀ-ከል አንሳ</translation> <translation id="1293264513303784526">USB-C መሣሪያ (የግራ ወደብ)</translation> <translation id="1293556467332435079">ፋይሎች</translation> <translation id="1296497012903089238">የእውቅና ማረጋገጫ አይነት</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">መነሻ ገጽ አዲሱ የትር ገጽ ነው</translation> <translation id="1436671784520050284">ማዋቀር ቀጥል</translation> <translation id="1436784010935106834">ተወግዷል</translation> -<translation id="1438632560381091872">የትሮች ድምጸ-ከል አንሳ</translation> <translation id="1442392616396121389">የመሄጃ ቅድመ ቅጥያ</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> ተመርጠዋል</translation> <translation id="1444628761356461360">ይህ ቅንብር በመሣሪያው ባለቤት በ <ph name="OWNER_EMAIL" /> ነው የሚቀናበረው።</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">የእርስዎን የይለፍ ቃል ለመጨረሻ ጊዜ ካስገቡ ወዲህ የተለየ የቁልፍ ሰሌዳ ተገናኝቷል። የእርስዎን የቁልፍ ጭረቶች ለመስረቅ እየሞከረ ሊሆን ይችላል።</translation> <translation id="1567750922576943685">ማንነትዎን ማረጋገጥ የግል መረጃዎ እንዲጠበቅ ያግዛል</translation> <translation id="1567993339577891801">ጃቫስክሪፕት ኮንሶል</translation> -<translation id="1568067597247500137">ጣቢያ ላይ ድምፀ-ከል አድርግ</translation> <translation id="1568323446248056064">የማሳያ የመሣሪያ ቅንብሮችን ክፈት</translation> <translation id="1572266655485775982">Wi-Fi አንቃ</translation> <translation id="1572585716423026576">እንደ ልጣፍ አዘጋጅ</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">የX9.62 ECDSA ፊርማ በSHA-1</translation> <translation id="1644574205037202324">ታሪክ</translation> <translation id="1645516838734033527">የእርስዎን <ph name="DEVICE_TYPE" /> ደህንነቱ እንደተጠበቀ ለማቆየት Smart Lock በእርስዎ ስልክ ላይ የማያ ገጽ መቆለፊያ ያስፈልገዋል።</translation> -<translation id="1646102270785326155">አንዴ እነኚህ ተጠቃሚ ከተወገዱ በኋላ ከዚህ ተጠቃሚ ጋር የተጎዳኙ ሁሉም ፋይሎች እና አካባቢያዊ ውሂብ በቋሚነት ይሰረዛሉ። $1 አሁንም በኋላ ላይ ወደ መለያ መግባት ይችላሉ።</translation> <translation id="1646982517418478057">ይህን የዕውቅና ማረጋገጫ ፋይል ለማመስጠር እባክዎ የይለፍ ቃል ያስገቡ</translation> <translation id="164814987133974965">በቁጥጥር ስር ያለ ተጠቃሚ እርስዎ እየመሩት ድርን ማሰስ ይችላል። በቁጥጥር ስር ያለ ተጠቃሚ አስተዳዳሪ እንደመሆንዎ፣ የሚከተሉትን ማድረግ ይችላሉ የተወሰኑ ድር ጣቢያዎችን <ph name="BEGIN_BOLD" />መፍቃድ ወይም መከልከል<ph name="END_BOLD" />፣ @@ -499,7 +493,6 @@ <translation id="1729533290416704613">እንዲሁም ከኦምኒቦክሱ ሆነው ሲፈልጉ የሚታየውን ገጽ ይቆጣጠራል።</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />መተግበሪያዎችን ለማስወገድ ወደ ቅንብሮች > Google Play መደብር > የAndroid ምርጫዎችን ያስተዳድሩ >መተግበሪያዎች ወይም የመተግበሪያ አስተዳዳሪ ይሂዱ። ከዚያ ለማራገፍ የሚፈልጉትን መተግበሪያ መታ ያድርጉ (መተግበሪያውን ለማግኘት ወደ ቀኝ ወይም ወደ ግራ ማንሸራተት ሊኖርብዎት ይችላል)። ከዚያ አራግፍ ወይም አሰናክል የሚለውን መታ ያድርጉ።<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">ጥያቄ በመላክ ላይ...</translation> -<translation id="1732215134274276513">ትሮችን ይንቀሉ</translation> <translation id="1733383495376208985">የሰመረ ውሂብ በራስዎ <ph name="BEGIN_LINK" />የስምረት ይለፍ ሐረግ<ph name="END_LINK" /> ያመስጥሩ። ይህ ከGoogle Pay የመክፈያ ዘዴዎችን እና አድራሻዎችን አያካትትም።</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> ራሱን እያዘመነ ላይቀጥል ይችላል</translation> <translation id="1736419249208073774">አስስ</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">ሁሉም ፋይሎች</translation> <translation id="1809734401532861917">የእኔን እልባቶች፣ ታሪክ፣ የይለፍ ቃሎች እና ሌሎች ቅንብሮችን ወደ <ph name="USER_EMAIL_ADDRESS" /> አክል</translation> <translation id="1810764548349082891">ምንም ቅድመ-እይታ አይገኝም</translation> -<translation id="1812631533912615985">ትሮችን ይንቀሉ</translation> <translation id="1813278315230285598">ግልጋሎቶች</translation> <translation id="18139523105317219">EDI ፓርቲ ስም</translation> <translation id="1815083418640426271">እንደ ስነጣ አልባ ጽሑፍ ለጥፍ</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chrome በራስ-ሰር የሙከራ ሶፍትዌር ቁጥጥር ሥር ነው።</translation> <translation id="2070909990982335904">በነጥብ የሚጀምሩ ስሞች ለስርዓቱ የተቀመጡ ናቸው። እባክዎ ሌላ ስም ይምረጡ።</translation> <translation id="2071393345806050157">ምንም አካባቢያዊ የምዝግብ ማስታወሻ ፋይል የለም።</translation> -<translation id="2074527029802029717">ትር ይንቀሉ</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% ባትሪ</translation> <translation id="2075959085554270910">ለጠቅታ-መታ ማድረግን እንዲያነቁ/እንዲያሰናክሉ እና ለመጎተት መታ ማድረግ ያስችልዎታል</translation> <translation id="2076269580855484719">ይህን ተሰኪ ደብቅ</translation> @@ -1356,7 +1347,6 @@ <translation id="3045447014237878114">ይህ ጣቢያ በርካታ ፋይሎችን በራስ-ሰር አውርዷል</translation> <translation id="3046910703532196514">ድረ-ገጽ፣ ሙሉ</translation> <translation id="304747341537320566">የንግግር ፕሮግራሞች</translation> -<translation id="304826556400666995">የትሮች ድምጸ-ከል አንሳ</translation> <translation id="3053013834507634016">የሰርቲፊኬት ቁልፍ ጠቀሜታ</translation> <translation id="3057861065630527966">የእርስዎን ፎቶዎች እና ቪዲዮዎች በምትኬ ያስቀምጡ</translation> <translation id="3060379269883947824">ለመናገር-ይምረጡን ያንቁ</translation> @@ -2340,7 +2330,6 @@ <translation id="4628762811416793313">የLinux መያዣው ውቅረት አልተጠናቀቀም። እባክዎ እንደገና ይሞክሩ።</translation> <translation id="4628948037717959914">ፎቶ</translation> <translation id="4631887759990505102">አርቲስት</translation> -<translation id="4632483769545853758">የትር ድምጸ-ከል አንሳ</translation> <translation id="4633003931260532286">ቅጥያው ቢያንስ የ«<ph name="IMPORT_VERSION" />» ስሪት የሆነ «<ph name="IMPORT_NAME" />» ያስፈልገዋል፣ ነገር ግን «<ph name="INSTALLED_VERSION" />» ስሪት ብቻ ነው የተጫነው</translation> <translation id="4634771451598206121">እንደገና ይግቡ...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> ለእንግዳ ተጠቃሚዎች አይገኝም።</translation> @@ -2405,7 +2394,6 @@ <translation id="4736292055110123391">የእርስዎን ዕልባቶች፣ የይለፍ ቃላት፣ ታሪክ እና ተጨማሪ ነገሮች በሁሉም መሣሪያዎችዎ ላይ ያሳምሩ</translation> <translation id="4737715515457435632">እባክዎ ከአንድ አውታረ መረብ ጋር ይገናኙ</translation> <translation id="473775607612524610">አዘምን</translation> -<translation id="474217410105706308">ትር ላይ ድምጸ-ከል አድርግ</translation> <translation id="4742746985488890273">መደርደሪያ ላይ ሰካ</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />እንዴት መተግበሪያዎችን ማዘመን እንደሚቻል ይረዱ<ph name="END_LINK" /></translation> <translation id="4746351372139058112">መልዕክቶች</translation> @@ -2630,7 +2618,6 @@ <translation id="5094721898978802975">ከተባባሪ ቤተኛ መተግበሪያዎች ጋር ተገናኝ</translation> <translation id="5097002363526479830">ከአውታረ መረብ «<ph name="NAME" />» ጋር መገናኘት አልተሳካም፦ <ph name="DETAILS" /></translation> <translation id="5101042277149003567">ሀሉንም እልባቶች ክፈት</translation> -<translation id="5105855035535475848">ትሮችን ይሰኩ</translation> <translation id="5108967062857032718">ቅንብሮች - የAndroid መተግበሪያዎችን አስወግድ</translation> <translation id="5109044022078737958">ሚያ</translation> <translation id="5111692334209731439">&ዕልባት አቀናባሪ</translation> @@ -2695,7 +2682,6 @@ <translation id="520621735928254154">የእውቅና ማረጋገጫ ማስመጣት ስህተት</translation> <translation id="5209320130288484488">ምንም መሣሪያዎች አልተገኙም</translation> <translation id="5209518306177824490">SHA-1 የጣት አሻራ</translation> -<translation id="5210365745912300556">ትር ዝጋ</translation> <translation id="5213481667492808996">የእርስዎ የ«<ph name="NAME" />» ውሂብ አገልግሎት ጥቅም ላይ ለመዋል ዝግጁ ነው</translation> <translation id="5213891612754844763">የተኪ ቅንብሮችን አሳይ</translation> <translation id="521582610500777512">ፎቶ ተጥሏል</translation> @@ -2747,7 +2733,6 @@ <translation id="5272654297705279635">ብጁ ቅንብሮች</translation> <translation id="5275352920323889391">ውሻ</translation> <translation id="5275973617553375938">ከGoogle Drive መልሰው የተገኙ ፋይሎች</translation> -<translation id="527605719918376753">ትር ላይ ድምጸ-ከል አድርግ</translation> <translation id="527605982717517565">ሁልጊዜ በ<ph name="HOST" /> ላይ ጃቫስክሪፕት ፍቀድ</translation> <translation id="5280426389926346830">አቋራጭ ይፈጠር?</translation> <translation id="528208740344463258">የAndroid መተግበሪያዎችን ለማውረድ እና ለመጠቀም በመጀመሪያ ይህን የሚያስፈልግ ዝማኔ መጫን አለብዎት። የእርስዎ <ph name="DEVICE_TYPE" /> እያዘመነ ሳለ ሊጠቀሙበት አይችሉም። መጫን ከተጠናቀቀ በኋላ የእርስዎ <ph name="DEVICE_TYPE" /> ዳግም ይነሳል።</translation> @@ -2870,7 +2855,6 @@ <translation id="5449551289610225147">ልክ ያልኾነ የይለፍ ቃል</translation> <translation id="5449588825071916739">ለሁሉም ትሮች ዕልባት አብጅ</translation> <translation id="5449716055534515760">&መስኮት ዝጋ</translation> -<translation id="5453029940327926427">ትሮችን ይዝጉ</translation> <translation id="5454166040603940656">ከ<ph name="PROVIDER" /> ጋር</translation> <translation id="5457113250005438886">ልክ ያልሆነ</translation> <translation id="5457459357461771897">በኮምፒውተርዎ ላይ ፎቶዎችን፣ ሙዚቃ እና ሌላ ማህደረ መረጃን ያነብባል</translation> @@ -3334,7 +3318,6 @@ <translation id="6122875415561139701">የመጻፍ ክወና በዚህ ላይ አይፈቀድም፦ «<ph name="DEVICE_NAME" />»።</translation> <translation id="6124650939968185064">የሚከተሉት ቅጥያዎች በዚህ ቅጥያ ላይ ይወሰናሉ፦</translation> <translation id="6125479973208104919">የአጋጣሚ ነገር ሆኖ መለያዎን እንደገና ወደዚህ <ph name="DEVICE_TYPE" /> ማከል አለብዎት።</translation> -<translation id="612596694132302162">ከጣቢያ ድምፀ-ከል አንሳ</translation> <translation id="6129691635767514872">የተመረጠው ውሂብ ከChrome እና የሰመሩ መሣሪያዎች ተወግዷል። የGoogle መለያዎ <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> ላይ እንደ የሌሎች Google አገልግሎቶች ፍለጋዎች እና እንቅስቃሴ ያለ ሌሎች የአሰሳ ታሪክ ዓይነት ሊኖረው ይችላል።</translation> <translation id="6129938384427316298">የNetscape ሰርቲፊኬት አስተያየት</translation> <translation id="6129953537138746214">ባዶ ቦታ</translation> @@ -3537,7 +3520,6 @@ <translation id="6436164536244065364">በድር መደብር ውስጥ ይመልከቱ</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - ኦዲዮ በመጫወት ላይ ነው</translation> <translation id="6442187272350399447">ግሩም</translation> -<translation id="6442697326824312960">ትር መጣበቅን አላቅ</translation> <translation id="6444070574980481588">ቀን እና ሰዓት ያዘጋጁ</translation> <translation id="6445450263907939268">እነዚህን ለውጦች ካልፈለጓቸው ቀዳሚዎቹ ቅንብሮችዎን ወደነበሩበት መመለስ ይችላሉ።</translation> <translation id="6447842834002726250">ኩኪዎች</translation> @@ -3740,7 +3722,6 @@ <translation id="6770664076092644100">በNFC በኩል አረጋግጥ</translation> <translation id="6771503742377376720">የእውቅና ማረጋገጫ ባለስልጣን ነው</translation> <translation id="6777817260680419853">አቅጣጫ ማዞር ታግዷል</translation> -<translation id="6778959797435875428">ከጣቢያዎች ድምፀ-ከል አንሳ</translation> <translation id="677965093459947883">በጣም ትንሽ</translation> <translation id="6780439250949340171">ሌሎች ቅንብሮችን ያቀናብሩ</translation> <translation id="6781284683813954823">Doodle አገናኝ</translation> @@ -4057,7 +4038,6 @@ <translation id="7257666756905341374">የሚቀዱትን እና የሚለጥፉትን ውሂብ ያነብባል</translation> <translation id="7258697411818564379">የእርስዎ ፒን ታክሏል</translation> <translation id="7262004276116528033">ይህ የመለያ መግቢያ አገልግሎት በ<ph name="SAML_DOMAIN" /> የሚስተናገድ ነው</translation> -<translation id="7268365133021434339">ትሮችን ዝጋ</translation> <translation id="7268659760406822741">የሚገኙ አገልግሎቶች</translation> <translation id="7270858098575133036">አንድ ጣቢያ የMIDI መሣሪያዎችን ለመድረስ ለሚመለከተው ሥርዓት ብቻ የተወሰኑ መልእክቶችን ለመጠቀም ሲፈልግ ጠይቅ</translation> <translation id="7272674038937250585">ምንም መግለጫ አልቀረበም</translation> @@ -4247,7 +4227,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">አጠናክር</translation> <translation id="7576976045740938453">በቅንጭብ ማሳያ ሁነታ መለያ ላይ አንድ ችግር አጋጥሟል።</translation> -<translation id="7579149537961810247">ጣቢያዎች ላይ ድምፀ-ከል አድርግ</translation> <translation id="7580671184200851182">ተመሳሳዩን ኦዲዮ በሁሉም ድምፅ ማጉያዎች በኩል አጫውት (ሞኖ ኦዲዮ)</translation> <translation id="7581462281756524039">የማጽጃ መሣሪያ</translation> <translation id="7582582252461552277">ይህን አውታረ መረብ አስቀድመው ይምረጡ</translation> @@ -4606,7 +4585,6 @@ <translation id="8068253693380742035">በመለያ ለመግባት ይንኩ</translation> <translation id="8069615408251337349">Google ዳመና ህትመት</translation> <translation id="8071432093239591881">እንደ ምስል አስቀምጥ</translation> -<translation id="8072988827236813198">ትሮችን ይሰኩ</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />የመተግበሪያ ውሂብ እንደ እውቂያዎች፣ መልዕክቶች፣ እና ፎቶዎች ያለ ውሂብንም ጨምሮ አንድ መተግበሪያ የሚያስቀምጠው ማንኛውም ውሂብ ሊሆን ይችላል (በገንቢው ቅንብሮች ላይ የሚወሰን)።<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />የምትኬ ውሂብ በእርስዎ ልጅ የDrive ማከማቻ ኮታ ላይ አይቆጠርም።<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />ይህን አገልግሎት በቅንብሮች ውስጥ ማጥፋት ይችላሉ።<ph name="END_PARAGRAPH3" /></translation> @@ -4791,7 +4769,6 @@ <translation id="8368859634510605990">&ሁሉንም እልባቶች ክፈት</translation> <translation id="8371695176452482769">አሁን ይናገሩ</translation> <translation id="8372369524088641025">መጥፎ የWEP ቁልፍ</translation> -<translation id="8373553483208508744">ትሮች ላይ ድምጸ-ከል ያድርጉ</translation> <translation id="8378714024927312812">በእርስዎ ድርጅት የሚተዳደር</translation> <translation id="8379878387931047019">ይህ መሣሪያ በዚህ ድር ጣቢያ የተጠየቀውን የደህንነት ቁልፍ አይነት አይደግፍም</translation> <translation id="8382913212082956454">&ኢሜይል አድራሻ ቅዳ</translation> @@ -4899,7 +4876,6 @@ <translation id="8546930481464505581">ተነኪ አሞሌን አብጅ</translation> <translation id="8547013269961688403">የሙሉ ገጽ እይታ ማጉያን ያንቁ</translation> <translation id="85486688517848470">የላይኛው ረድፍ ቁልፎች ባህሪን ለመቀየር የፍለጋ ቁልፉን ይያዙ</translation> -<translation id="855081842937141170">ትር አጣብቅ</translation> <translation id="8551388862522347954">ፍቃዶች</translation> <translation id="8553342806078037065">ሌሎች ሰዎችን አቀናብር</translation> <translation id="8554899698005018844">ምንም ቋንቋ</translation> @@ -5214,7 +5190,6 @@ <translation id="9038430547971207796">በሚቀጥለው ጊዜ የእርስዎ ስልክ የእርስዎን <ph name="DEVICE_TYPE" /> ይከፍተዋል። በቅንብሮች ውስጥ Smart Lockን ያብሩ።</translation> <translation id="9038649477754266430">ገጾችን ይበልጥ በፍጥነት ለመጫን የግመታ አገልግሎትን ይጠቀሙ</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">ትሮች ላይ ድምጸ-ከል ያድርጉ</translation> <translation id="9040661932550800571">ለ<ph name="ORIGIN" /> የይለፍ ቃል ይዘምን?</translation> <translation id="9041692268811217999">ማሽንዎ ላይ የአካባቢያዊ ፋይሎች መዳረሻ በአስተዳዳሪዎ ተሰናክሏል</translation> <translation id="9042893549633094279">ግላዊነት እና ደኅንነት</translation> @@ -5312,7 +5287,6 @@ <translation id="920045321358709304"><ph name="SEARCH_ENGINE" />ን ፈልግ</translation> <translation id="9201220332032049474">የማያ ገጽ መቆለፊያ አማራጮች</translation> <translation id="9203398526606335860">&መገለጫ መስራት ነቅቷል</translation> -<translation id="9203478404496196495">የትሮች ድምጸ-ከል አንሳ</translation> <translation id="9203904171912129171">መሣሪያ ይምረጡ</translation> <translation id="9203962528777363226">የዚህ መሣሪያ አስተዳዳሪ አዲስ ተጠቃሚዎች እንዳይታከሉ አሰናክሏል</translation> <translation id="9213073329713032541">ጭነት በተሳካ ሁኔታ ጀምሯል።</translation>
diff --git a/chrome/app/resources/generated_resources_ar.xtb b/chrome/app/resources/generated_resources_ar.xtb index 334f4b5..e728ceb 100644 --- a/chrome/app/resources/generated_resources_ar.xtb +++ b/chrome/app/resources/generated_resources_ar.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">اضغط على ESCAPE للتخطي (الإصدارات غير الرسمية فقط).</translation> <translation id="1093457606523402488">شبكات مرئية:</translation> <translation id="1094607894174825014">تم طلب عملية القراءة أو الكتابة باستخدام إزاحة غير صالحة على: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">إلغاء تجاهل المواقع</translation> <translation id="1097658378307015415">قبل تسجيل الدخول، يُرجى الدخول كضيف لتفعيل الشبكة <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">ترجمة اللغة <ph name="LANGUAGE" /> دائمًا</translation> <translation id="1108600514891325577">إي&قاف</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">استخدِم الويب دون حفظ سجلّ التصفُّح باستخدام نافذة تصفُّح متخفٍ</translation> <translation id="1213037489357051291">تم إعداد <ph name="NUM_FINGERPRINTS" /> من بصمات الإصبع</translation> <translation id="1215411991991485844">تمت إضافة تطبيق جديد في الخلفية</translation> -<translation id="1216654534877302979">تجاهل المواقع</translation> <translation id="1216659994753476700">عذرًا، لا يمكننا الوصول إلى ملفك الشخصي. ربما تم فقد الملفات والبيانات المخزنة على هذا الجهاز.<ph name="BR" /> <ph name="BR" /> سيلزمك إعداد ملفك الشخصي مرةً أخرى.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">تخزين البيانات في حساب Google Drive</translation> <translation id="1288037062697528143">سيتم تشغيل الإضاءة الليلية تلقائيًا عند غروب الشمس.</translation> <translation id="1288300545283011870">خصائص الكلام</translation> -<translation id="1293177648337752319">إلغاء تجاهل الموقع</translation> <translation id="1293264513303784526">جهاز USB-C (المنفذ الأيسر)</translation> <translation id="1293556467332435079">ملفات</translation> <translation id="1296497012903089238">نوع الشهادة</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">الصفحة الرئيسية هي صفحة "علامة تبويب جديدة"</translation> <translation id="1436671784520050284">متابعة الإعداد</translation> <translation id="1436784010935106834">تمت الإزالة</translation> -<translation id="1438632560381091872">إلغاء تجاهل علامات التبويب</translation> <translation id="1442392616396121389">بادئة توجيه</translation> <translation id="144283815522798837">تم تحديد <ph name="NUMBER_OF_ITEMS_SELECTED" /> من العناصر</translation> <translation id="1444628761356461360">يتولى إدارة هذا الإعداد مالك الجهاز، <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">تم توصيل لوحة مفاتيح مختلفة منذ آخر إدخال لكلمة المرور، وقد يكون ذلك محاولةً لسرقة ضغطات المفاتيح.</translation> <translation id="1567750922576943685">يساعد التحقُّق من هويتك في حماية معلوماتك الشخصية</translation> <translation id="1567993339577891801">وحدة تحكم جافا سكريبت</translation> -<translation id="1568067597247500137">تجاهل الموقع</translation> <translation id="1568323446248056064">فتح إعدادات الجهاز للعرض</translation> <translation id="1572266655485775982">تفعيل شبكة Wi-Fi</translation> <translation id="1572585716423026576">تحديد كخلفية</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">توقيع X9.62 ECDSA باستخدام SHA-1</translation> <translation id="1644574205037202324">السجل</translation> <translation id="1645516838734033527">للحفاظ على جهاز <ph name="DEVICE_TYPE" /> آمنًا، يتطلب Smart Lock قفل الشاشة على هاتفك.</translation> -<translation id="1646102270785326155">سيتم حذف جميع الملفات والبيانات المحلية المرتبطة بهذا المستخدم نهائيًا فور إزالة هذا المستخدم. وسيظل بإمكان $1 تسجيل الدخول لاحقًا.</translation> <translation id="1646982517418478057">يُرجى إدخال كلمة مرور لتشفير هذه الشهادة</translation> <translation id="164814987133974965">يمكن للمستخدم الذي يخضع للإدارة استكشاف الويب بتوجيه منك. وبصفتك مديرًا للمستخدم الذي يخضع للإدارة، يمكنك <ph name="BEGIN_BOLD" />السماح لمواقع ويب معينة أو حظرها<ph name="END_BOLD" />، @@ -499,7 +493,6 @@ <translation id="1729533290416704613">كما أنها تتحكم في الصفحة التي تظهر عند إجراء بحث من المربع متعدد الاستخدامات.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />لإزالة التطبيقات، يمكنك الانتقال إلى "الإعدادات" > "متجر Google Play" > "إدارة إعدادات Android المفضّلة" > "التطبيقات" أو "مدير التطبيقات". وبعد ذلك، انقر على التطبيق الذي تريد إلغاء تثبيته (قد يجب التمرير سريعًا إلى اليمين أو اليسار للعثور على التطبيق). ثم انقر على "إلغاء التثبيت" أو "إيقاف".<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">إرسال الطلب...</translation> -<translation id="1732215134274276513">إزالة تثبيت علامات التبويب</translation> <translation id="1733383495376208985">تشفير البيانات المتزامنة باستخدام <ph name="BEGIN_LINK" />عبارة مرور المزامنة<ph name="END_LINK" /> الخاصة بك. لا يتضمّن ذلك طرق الدفع والعناوين من Google Pay.</translation> <translation id="1734824808160898225">قد لا يتمكَّن <ph name="PRODUCT_NAME" /> من الاستمرار في تحديث نفسه.</translation> <translation id="1736419249208073774">استكشاف</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">كل الملفات</translation> <translation id="1809734401532861917">إضافة الإشارات المرجعية، والسّجل، وكلمات المرور، والإعدادات الأخرى إلى <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">لا تتوفر معاينة</translation> -<translation id="1812631533912615985">إزالة تثبيت علامات التبويب</translation> <translation id="1813278315230285598">الخدمات</translation> <translation id="18139523105317219">اسم جهة تبادل البيانات الإلكتروني (EDI)</translation> <translation id="1815083418640426271">لصق كنص عادي</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">يتم التحكم في Chrome من خلال برامج اختبار تلقائية.</translation> <translation id="2070909990982335904">الأسماء البادئة بنقطة محجوزة للنظام. يرجى اختيار اسم آخر.</translation> <translation id="2071393345806050157">ليس هناك ملف سجل محلي.</translation> -<translation id="2074527029802029717">إزالة تثبيت علامة التبويب</translation> <translation id="2075474481720804517">البطارية <ph name="BATTERY_PERCENTAGE" />%</translation> <translation id="2075959085554270910">تتيح لك تفعيل ميزة الضغط للنقر وميزة السحب بالنقر أو إيقافهما.</translation> <translation id="2076269580855484719">إخفاء هذا المكون الإضافي</translation> @@ -1356,7 +1347,6 @@ <translation id="3045447014237878114">نزَّل هذا الموقع عدة ملفات تلقائيًا</translation> <translation id="3046910703532196514">صفحة الويب، كاملة</translation> <translation id="304747341537320566">محركات الكلام</translation> -<translation id="304826556400666995">إلغاء تجاهل علامات التبويب</translation> <translation id="3053013834507634016">استخدام مفتاح الشهادة</translation> <translation id="3057861065630527966">نسخ الصور والفيديوهات احتياطيًا</translation> <translation id="3060379269883947824">تفعيل الاختيار والاستماع</translation> @@ -2338,7 +2328,6 @@ <translation id="4628762811416793313">لم يكتمل إعداد حاوية نظام التشغيل Linux. يُرجى إعادة المحاولة.</translation> <translation id="4628948037717959914">صورة</translation> <translation id="4631887759990505102">الفنان</translation> -<translation id="4632483769545853758">إلغاء تجاهل علامة التبويب</translation> <translation id="4633003931260532286">تتطلب الإضافة "<ph name="IMPORT_NAME" />" بإصدار لا يقل عن "<ph name="IMPORT_VERSION" />" لكن يتم تثبيت "<ph name="INSTALLED_VERSION" />" فقط.</translation> <translation id="4634771451598206121">تسجيل الدخول مرة أخرى...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> غير متاحة للمستخدمين الضيوف.</translation> @@ -2403,7 +2392,6 @@ <translation id="4736292055110123391">مزامنة الإشارات المرجعية وكلمات المرور والسجلّ وغيرها على جميع أجهزتك</translation> <translation id="4737715515457435632">يُرجى الاتصال بشبكة.</translation> <translation id="473775607612524610">تحديث</translation> -<translation id="474217410105706308">تجاهل علامة التبويب</translation> <translation id="4742746985488890273">تثبيت في الرف</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />التعرّف على كيفية تحديث التطبيقات<ph name="END_LINK" /></translation> <translation id="4746351372139058112">الرسائل</translation> @@ -2628,7 +2616,6 @@ <translation id="5094721898978802975">الاتصال بتطبيقات التعاون الأصلية</translation> <translation id="5097002363526479830">تعذّر الاتصال بشبكة "<ph name="NAME" />": <ph name="DETAILS" /></translation> <translation id="5101042277149003567">فتح جميع الإشارات المرجعية</translation> -<translation id="5105855035535475848">تثبيت علامات التبويب</translation> <translation id="5108967062857032718">الإعدادات - إزالة تطبيقات Android</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">&مدير الإشارات</translation> @@ -2693,7 +2680,6 @@ <translation id="520621735928254154">خطأ في استيراد الشهادة</translation> <translation id="5209320130288484488">لم يتم العثور على أي أجهزة</translation> <translation id="5209518306177824490">بصمة أصبع SHA-1</translation> -<translation id="5210365745912300556">إغلاق علامة التبويب</translation> <translation id="5213481667492808996">خدمة بيانات "<ph name="NAME" />" جاهزة للاستخدام</translation> <translation id="5213891612754844763">عرض إعدادات الخادم الوكيل</translation> <translation id="521582610500777512">تم تجاهل الصورة</translation> @@ -2745,7 +2731,6 @@ <translation id="5272654297705279635">الإعدادات المُخصَّصة</translation> <translation id="5275352920323889391">كلب</translation> <translation id="5275973617553375938">الملفات المستردة من Google Drive</translation> -<translation id="527605719918376753">تجاهل علامة التبويب</translation> <translation id="527605982717517565">السماح بتشغيل جافا سكريبت على الموقع <ph name="HOST" /> دومًا</translation> <translation id="5280426389926346830">هل تريد إنشاء اختصار؟</translation> <translation id="528208740344463258">لتنزيل تطبيقات Android واستخدامها، تحتاج أولاً إلى تثبيت هذا التحديث. يُذكر أنه لا يمكنك استخدام جهاز <ph name="DEVICE_TYPE" /> أثناء تحديثه وستتم إعادة تشغيل <ph name="DEVICE_TYPE" /> بعد اكتمال التثبيت.</translation> @@ -2868,7 +2853,6 @@ <translation id="5449551289610225147">كلمة المرور غير صالحة</translation> <translation id="5449588825071916739">وضع إشارة على جميع علامات التبويب</translation> <translation id="5449716055534515760">إغلاق &النافذة</translation> -<translation id="5453029940327926427">إغلاق علامات التبويب</translation> <translation id="5454166040603940656">مع <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">غير صالحة</translation> <translation id="5457459357461771897">التعرّف على الصور، والموسيقى، والوسائط الأخرى من الكمبيوتر وحذفها</translation> @@ -3333,7 +3317,6 @@ <translation id="6122875415561139701">لا يُسمح بعملية الكتابة على: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">تعتمد الإضافات التالية على هذه الإضافة:</translation> <translation id="6125479973208104919">عذرًا، ستحتاج إلى إضافة حسابك إلى جهاز <ph name="DEVICE_TYPE" /> هذا مرة أخرى.</translation> -<translation id="612596694132302162">إلغاء تجاهل الموقع</translation> <translation id="6129691635767514872">تمت إزالة البيانات المحددة من Chrome والأجهزة التي تمت مزامنتها. قد يحتوي حسابك على Google على نماذج أخرى من سجل التصفح، مثل عمليات البحث والنشاط من خدمات Google الأخرى في <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">التعليق على شهادة Netscape</translation> <translation id="6129953537138746214">مسافة</translation> @@ -3537,7 +3520,6 @@ <translation id="6436164536244065364">عرض في السوق الإلكتروني</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - تشغيل الصوت</translation> <translation id="6442187272350399447">الروعة</translation> -<translation id="6442697326824312960">إزالة تثبيت علامة التبويب</translation> <translation id="6444070574980481588">تعيين التاريخ والوقت</translation> <translation id="6445450263907939268">إذا كنت لا تريد هذه التغييرات، فيمكنك استعادة الإعدادات السابقة.</translation> <translation id="6447842834002726250">ملفّات تعريف الارتباط</translation> @@ -3740,7 +3722,6 @@ <translation id="6770664076092644100">التحقُّق عبر NFC</translation> <translation id="6771503742377376720">هو مرجع مصدق</translation> <translation id="6777817260680419853">تم حظر إعادة التوجيه</translation> -<translation id="6778959797435875428">إلغاء تجاهل المواقع</translation> <translation id="677965093459947883">صغير جدًا</translation> <translation id="6780439250949340171">إدارة الإعدادات الأخرى</translation> <translation id="6781284683813954823">رابط رسومات الشعار المبتكرة</translation> @@ -4057,7 +4038,6 @@ <translation id="7257666756905341374">قراءة البيانات التي نسختها ولصقتها</translation> <translation id="7258697411818564379">تمت إضافة رقم التعريف الشخصي</translation> <translation id="7262004276116528033">يستضيف <ph name="SAML_DOMAIN" /> خدمة تسجيل الدخول هذه.</translation> -<translation id="7268365133021434339">إغلاق علامات التبويب</translation> <translation id="7268659760406822741">الخدمات المتوفرة</translation> <translation id="7270858098575133036">طلب الإذن عند محاولة أحد المواقع استخدام رسائل حصرية للنظام للوصول إلى أجهزة MIDI</translation> <translation id="7272674038937250585">لم يتم تقديم أي وصف</translation> @@ -4247,7 +4227,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">تجميع</translation> <translation id="7576976045740938453">حدثت مشكلة في حساب الوضع التجريبي.</translation> -<translation id="7579149537961810247">تجاهل المواقع</translation> <translation id="7580671184200851182">تشغيل نفس الصوت عبر جميع مكبرات الصوت (صوت أحادي)</translation> <translation id="7581462281756524039">أداة إزالة البرامج</translation> <translation id="7582582252461552277">تفضيل هذه الشبكة</translation> @@ -4601,7 +4580,6 @@ <translation id="8068253693380742035">المس لتسجيل الدخول</translation> <translation id="8069615408251337349">الطباعة السحابية من Google</translation> <translation id="8071432093239591881">الطباعة كصورة</translation> -<translation id="8072988827236813198">تثبيت علامات التبويب</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />قد تكون بيانات التطبيق أي بيانات حفِظها التطبيق (استنادًا إلى إعدادات مطوِّر البرامج)، بما في ذلك البيانات مثل جهات الاتصال والرسائل والصور.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />لن تُحتَسَب بيانات النسخ الاحتياطي ضمن حصة طفلك في "التخزين في Drive".<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />يمكنك إيقاف هذه الخدمة في "الإعدادات".<ph name="END_PARAGRAPH3" /></translation> @@ -4787,7 +4765,6 @@ <translation id="8368859634510605990">&فتح كل الإشارات المرجعية</translation> <translation id="8371695176452482769">تحدث الآن</translation> <translation id="8372369524088641025">مفتاح WEP غير صالح</translation> -<translation id="8373553483208508744">تجاهل علامات التبويب</translation> <translation id="8378714024927312812">بإدارة مؤسستك</translation> <translation id="8379878387931047019">لا يدعم هذا الجهاز نوع مفتاح الأمان الذي يطلبه هذا الموقع الإلكتروني.</translation> <translation id="8382913212082956454">نسخ عنوان البريد الإل&كتروني</translation> @@ -4895,7 +4872,6 @@ <translation id="8546930481464505581">تخصيص شريط اللمس</translation> <translation id="8547013269961688403">تفعيل المكبّر بملء الشاشة</translation> <translation id="85486688517848470">اضغط على مفتاح البحث باستمرار لتبديل سلوك مفاتيح الصف العلوي</translation> -<translation id="855081842937141170">تثبيت علامة التبويب</translation> <translation id="8551388862522347954">التراخيص</translation> <translation id="8553342806078037065">إدارة الأشخاص الآخرين</translation> <translation id="8554899698005018844">بدون لغة</translation> @@ -5210,7 +5186,6 @@ <translation id="9038430547971207796">في المرة القادمة، سيلغي هاتفك قفل جهاز <ph name="DEVICE_TYPE" />. أوقف تشغيل Smart Lock في الإعدادات.</translation> <translation id="9038649477754266430">استخدام إحدى خدمات التوقع لتحميل الصفحات بسرعة أكبر</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">تجاهل علامات التبويب</translation> <translation id="9040661932550800571">هل تريد تحديث كلمة المرور لـ <ph name="ORIGIN" />؟</translation> <translation id="9041692268811217999">أوقف المشرف إمكانية الوصول إلى الملفات المحلية على جهازك.</translation> <translation id="9042893549633094279">الخصوصية والأمان</translation> @@ -5308,7 +5283,6 @@ <translation id="920045321358709304">البحث في <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">خيارات قفل الشاشة</translation> <translation id="9203398526606335860">&التوصيف مفعّل</translation> -<translation id="9203478404496196495">إلغاء تجاهل علامة التبويب</translation> <translation id="9203904171912129171">اختيار جهاز</translation> <translation id="9203962528777363226">أوقف مشرف هذا الجهاز إمكانية إضافة مستخدمين جدد.</translation> <translation id="9213073329713032541">بدأ التثبيت بنجاح.</translation>
diff --git a/chrome/app/resources/generated_resources_bg.xtb b/chrome/app/resources/generated_resources_bg.xtb index 1b29af3..683979c9f 100644 --- a/chrome/app/resources/generated_resources_bg.xtb +++ b/chrome/app/resources/generated_resources_bg.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Натиснете „ESCAPE“ за пропускане (само в неофициалните версии).</translation> <translation id="1093457606523402488">Видими мрежи:</translation> <translation id="1094607894174825014">Операция за четене или запис с невалидно отместване бе заявена на: <ph name="DEVICE_NAME" />.</translation> -<translation id="109758035718544977">Включване на звука за сайтовете</translation> <translation id="1097658378307015415">Преди да влезете в профила си, моля, влезте като гост, за да активирате мрежата <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Винаги да се превежда от <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Стоп</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Отворете прозорец в режим „инкогнито“, за да използвате мрежата, без да се запазва история на сърфирането ви</translation> <translation id="1213037489357051291">Настроени са <ph name="NUM_FINGERPRINTS" /> отпечатъка</translation> <translation id="1215411991991485844">Добавено е ново приложение на заден план</translation> -<translation id="1216654534877302979">Заглушаване на сайтовете</translation> <translation id="1216659994753476700">За съжаление, не можем да осъществим достъп до потребителския ви профил. Възможно е съхраняваните на това устройство файлове и данни да са заличени.<ph name="BR" /> <ph name="BR" /> Ще се наложи да настроите отново потребителския си профил.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Съхраняване на данните в профила ви в Google Диск</translation> <translation id="1288037062697528143">Нощното осветление ще се включи автоматично по залез</translation> <translation id="1288300545283011870">Свойства на говора</translation> -<translation id="1293177648337752319">Включване на звука за сайта</translation> <translation id="1293264513303784526">USB-C устройство (левият порт)</translation> <translation id="1293556467332435079">Файлове</translation> <translation id="1296497012903089238">Тип сертификат</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Началната страница е новият раздел</translation> <translation id="1436671784520050284">Продължаване с настройването</translation> <translation id="1436784010935106834">Премахнато</translation> -<translation id="1438632560381091872">Включване отново на звука на разделите</translation> <translation id="1442392616396121389">Префикс за маршрутизиране</translation> <translation id="144283815522798837">Избрахте <ph name="NUMBER_OF_ITEMS_SELECTED" /></translation> <translation id="1444628761356461360">Тази настройка се управлява от собственика на устройството – <ph name="OWNER_EMAIL" />.</translation> @@ -385,7 +381,6 @@ <translation id="1567387640189251553">Свързана е различна клавиатура, откакто последно въведохте паролата си. Тя може да се опитва да записва кои клавиши натискате.</translation> <translation id="1567750922576943685">Потвърждаването на самоличността ви спомага за защитата на личната ви информация</translation> <translation id="1567993339577891801">Конзола на JavaScript</translation> -<translation id="1568067597247500137">Заглушаване на сайта</translation> <translation id="1568323446248056064">Отваряне на настройките за дисплея</translation> <translation id="1572266655485775982">Активиране на Wi-Fi</translation> <translation id="1572585716423026576">Задаване като тапет</translation> @@ -437,7 +432,6 @@ <translation id="1643072738649235303">Подпис по X9.62 ECDSA с SHA-1</translation> <translation id="1644574205037202324">История</translation> <translation id="1645516838734033527">За да бъде защитен вашият <ph name="DEVICE_TYPE" />, Smart Lock изисква опция за заключване на екрана на телефона ви.</translation> -<translation id="1646102270785326155">След като този потребител бъде премахнат, всички свързани с него файлове и локални данни ще се изтрият за постоянно. $1 пак ще може да влезе в профила си по-късно.</translation> <translation id="1646982517418478057">Моля, въведете парола за шифроване на този сертификат</translation> <translation id="164814987133974965">Контролираният потребител може да изследва мрежата с ваше напътствие. Като негов мениджър сте в състояние: <ph name="BEGIN_BOLD" />да разрешавате или забранявате<ph name="END_BOLD" /> определени уебсайтове; @@ -496,7 +490,6 @@ <translation id="1729533290416704613">То също контролира коя страница се показва при търсене от полето за всичко.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />За да премахнете приложения, отворете „Настройки“ > „Google Play Магазин“ > „Управление на предпочитанията за Android“ > „Приложения“ или мениджъра на приложенията. Докоснете това, което искате да деинсталирате (може да се наложи да прекарате пръст надясно или наляво, за да го намерите). Докоснете „Деинсталиране“ или „Деактивиране“.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Заявката се изпраща...</translation> -<translation id="1732215134274276513">Освобождаване на разделите</translation> <translation id="1733383495376208985">Шифроване на синхронизираните данни със собствения ви <ph name="BEGIN_LINK" />пропуск за синхронизиране<ph name="END_LINK" />. Това не включва начините на плащане и адресите от Google Pay.</translation> <translation id="1734824808160898225">Възможно е <ph name="PRODUCT_NAME" /> да не може да се поддържа актуален</translation> <translation id="1736419249208073774">Разглеждане</translation> @@ -548,7 +541,6 @@ <translation id="1807938677607439181">Всички файлове</translation> <translation id="1809734401532861917">Добавяне на моите отметки, история, пароли и други настройки към <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Няма налична визуализация</translation> -<translation id="1812631533912615985">Освобождаване на разделите</translation> <translation id="1813278315230285598">Услуги</translation> <translation id="18139523105317219">Име на EDI страна</translation> <translation id="1815083418640426271">Поставяне като неформатиран текст</translation> @@ -707,7 +699,6 @@ <translation id="2065405795449409761">Chrome се контролира от автоматизиран софтуер за тестване.</translation> <translation id="2070909990982335904">Имената, започващи с точка, са запазени за системата. Моля, изберете друго име.</translation> <translation id="2071393345806050157">Няма локален регистрационен файл.</translation> -<translation id="2074527029802029717">Освобождаване на раздела</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% батерия</translation> <translation id="2075959085554270910">Позволява ви да активирате/деактивирате кликването с докосване и преместването чрез докосване</translation> <translation id="2076269580855484719">Скриване на тази приставка</translation> @@ -1349,7 +1340,6 @@ <translation id="3045447014237878114">Този сайт е изтеглил автоматично няколко файла</translation> <translation id="3046910703532196514">Уеб страница, цялата</translation> <translation id="304747341537320566">Машини за синтезиран говор</translation> -<translation id="304826556400666995">Включване отново на звука на разделите</translation> <translation id="3053013834507634016">Използване на ключа на сертификата</translation> <translation id="3057861065630527966">Създаване на резервни копия на снимките и видеоклиповете ви</translation> <translation id="3060379269883947824">Активиране на функцията Прочитане на глас</translation> @@ -2334,7 +2324,6 @@ <translation id="4628762811416793313">Настройването на контейнера за Linux не завърши. Моля, опитайте отново.</translation> <translation id="4628948037717959914">Снимка</translation> <translation id="4631887759990505102">Изпълнител</translation> -<translation id="4632483769545853758">Включване отново на звука на раздела</translation> <translation id="4633003931260532286">Разширението изисква <ph name="IMPORT_VERSION" /> или по-нова версия на <ph name="IMPORT_NAME" />, но само <ph name="INSTALLED_VERSION" /> е инсталирана</translation> <translation id="4634771451598206121">Влизане отново...</translation> <translation id="4635398712689569051">Страницата „<ph name="PAGE_NAME" />“ не е достъпна за гости.</translation> @@ -2398,7 +2387,6 @@ <translation id="4735803855089279419">Системата не успя да определи идентификаторите за това устройство.</translation> <translation id="4737715515457435632">Моля, установете връзка с мрежа</translation> <translation id="473775607612524610">Актуализиране</translation> -<translation id="474217410105706308">Спиране на звука на раздела</translation> <translation id="4742746985488890273">Фиксиране в лавицата</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Научете как да актуализирате приложения<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Messages</translation> @@ -2623,7 +2611,6 @@ <translation id="5094721898978802975">Комуникация със съдействащи директно изпълнявани приложения</translation> <translation id="5097002363526479830">Свързването с мрежата „<ph name="NAME" />“ не бе успешно: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Отваряне на всички отметки</translation> -<translation id="5105855035535475848">Фиксиране на разделите</translation> <translation id="5108967062857032718">Настройки – Премахване на приложенията за Android</translation> <translation id="5109044022078737958">Мия</translation> <translation id="5111692334209731439">&Диспечер на отметките</translation> @@ -2688,7 +2675,6 @@ <translation id="520621735928254154">Грешка при импортирането на сертификата</translation> <translation id="5209320130288484488">Няма намерени устройства</translation> <translation id="5209518306177824490">Пръстов отпечатък SHA-1</translation> -<translation id="5210365745912300556">Затваряне на раздела</translation> <translation id="5213481667492808996">Услугата ви за данни „<ph name="NAME" />“ е готова за използване</translation> <translation id="5213891612754844763">Показване на настройките за прокси сървъра</translation> <translation id="521582610500777512">Снимката бе отхвърлена</translation> @@ -2739,7 +2725,6 @@ <translation id="5270167208902136840">Показване на още <ph name="NUMBER_OF_MORE_APPS" /> приложения</translation> <translation id="5275352920323889391">Куче</translation> <translation id="5275973617553375938">Възстановени от Google Диск файлове</translation> -<translation id="527605719918376753">Спиране на звука на раздела</translation> <translation id="527605982717517565">Да се разреши на <ph name="HOST" /> винаги да изпълнява JavaScript</translation> <translation id="5280426389926346830">Да се създаде ли пряк път?</translation> <translation id="528208740344463258">За да изтеглите и използвате приложения за Android, трябва първо да инсталирате тази задължителна актуализация. Докато устройството ви <ph name="DEVICE_TYPE" /> се актуализира, няма да можете да го използвате. След като процесът приключи, <ph name="DEVICE_TYPE" /> ще се рестартира.</translation> @@ -2862,7 +2847,6 @@ <translation id="5449551289610225147">Паролата е невалидна</translation> <translation id="5449588825071916739">Запазване на отметки към всички раздели</translation> <translation id="5449716055534515760">Затваряне на &прозореца</translation> -<translation id="5453029940327926427">Затваряне на разделите</translation> <translation id="5454166040603940656">с/ъс <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Невалидно</translation> <translation id="5457459357461771897">Четене и изтриване на снимки, музика и друга мултимедия от компютъра ви</translation> @@ -3328,7 +3312,6 @@ <translation id="6122875415561139701">Операцията за запис не е разрешена на: <ph name="DEVICE_NAME" />.</translation> <translation id="6124650939968185064">От това разширение зависят следните разширения:</translation> <translation id="6125479973208104919">За съжаление, трябва отново да добавите профила си към това устройство <ph name="DEVICE_TYPE" />.</translation> -<translation id="612596694132302162">Включване на звука за сайта</translation> <translation id="6129691635767514872">Избраните данни са премахнати от Chrome и синхронизираните устройства. Възможно е в профила ви в Google да има други видове история на сърфиране, съхранявани на адрес <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> – например търсения и активност от други наши услуги.</translation> <translation id="6129938384427316298">Коментар на сертификат на Netscape</translation> <translation id="6129953537138746214">Интервал</translation> @@ -3531,7 +3514,6 @@ <translation id="6436164536244065364">Преглед в уеб магазина</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – възпроизвежда се звук</translation> <translation id="6442187272350399447">Щастливец</translation> -<translation id="6442697326824312960">Освобождаване на раздела</translation> <translation id="6444070574980481588">Задаване на датата и часа</translation> <translation id="6445450263907939268">Ако не сте искали тези промени, можете да възстановите предишните си настройки.</translation> <translation id="6447842834002726250">„Бисквитки“</translation> @@ -3734,7 +3716,6 @@ <translation id="6770664076092644100">Потвърждаване чрез КБП</translation> <translation id="6771503742377376720">Е сертифициращ орган</translation> <translation id="6777817260680419853">Блокирано бе пренасочване</translation> -<translation id="6778959797435875428">Включване на звука за сайтовете</translation> <translation id="677965093459947883">Много малък</translation> <translation id="6780439250949340171">да управлявате други настройки.</translation> <translation id="6781284683813954823">Връзка към драскулката</translation> @@ -4051,7 +4032,6 @@ <translation id="7257666756905341374">Четене на данните, които копирате и поставяте</translation> <translation id="7258697411818564379">ПИН кодът ви е добавен</translation> <translation id="7262004276116528033">Тази услуга за вход се хоства от <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Затваряне на разделите</translation> <translation id="7268659760406822741">Налични услуги</translation> <translation id="7270858098575133036">Получаване на запитване, когато сайт иска да използва специални системни съобщения за достъп до MIDI устройствата</translation> <translation id="7272674038937250585">Няма описание</translation> @@ -4241,7 +4221,6 @@ <translation id="7576032389798113292">6 x 4</translation> <translation id="7576690715254076113">Комплектуване</translation> <translation id="7576976045740938453">Възникна проблем с профила за демонстрационен режим.</translation> -<translation id="7579149537961810247">Заглушаване на сайтовете</translation> <translation id="7580671184200851182">Възпроизвеждане на един и същ звук през всички високоговорители (моно)</translation> <translation id="7581462281756524039">Инструмент за почистване</translation> <translation id="7582582252461552277">Да се предпочита тази мрежа</translation> @@ -4595,7 +4574,6 @@ <translation id="8068253693380742035">Докоснете за вход в профила си</translation> <translation id="8069615408251337349">Google Отпечатване в облак</translation> <translation id="8071432093239591881">Отпечатване като изображение</translation> -<translation id="8072988827236813198">Фиксиране на разделите</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Данните на приложенията могат да бъдат всяка запазена от тях информация (въз основа на настройките за програмисти), включително контакти, съобщения и снимки.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Данните в резервното копие не заемат от квотата на използваното от детето ви хранилище на Диск.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Можете да изключите тази услуга от настройките.<ph name="END_PARAGRAPH3" /></translation> @@ -4781,7 +4759,6 @@ <translation id="8368859634510605990">&Отваряне на всички отметки</translation> <translation id="8371695176452482769">Говорете сега</translation> <translation id="8372369524088641025">Ключът за WEP е неправилен</translation> -<translation id="8373553483208508744">Спиране на звука на разделите</translation> <translation id="8378714024927312812">Управлява се от организацията ви</translation> <translation id="8379878387931047019">Устройството не поддържа типа ключ за сигурност, заявен от този уебсайт</translation> <translation id="8382913212082956454">Копиране на име&йл адреса</translation> @@ -4889,7 +4866,6 @@ <translation id="8546930481464505581">Персонализиране на лентата за докосване</translation> <translation id="8547013269961688403">Активиране на лупата за увеличаване на целия екран</translation> <translation id="85486688517848470">Задръжте клавиша „търсене“, за да промените поведението на клавишите от най-горния ред</translation> -<translation id="855081842937141170">Фиксиране на раздела</translation> <translation id="8551388862522347954">Лицензи</translation> <translation id="8553342806078037065">Управление на другите хора</translation> <translation id="8554899698005018844">Без език</translation> @@ -5203,7 +5179,6 @@ <translation id="9038430547971207796">Следващия път телефонът ви ще отключи вашия <ph name="DEVICE_TYPE" />. Можете да изключите Smart Lock от настройките.</translation> <translation id="9038649477754266430">Използване на услуга за предвиждане с цел по-бързо зареждане на страниците</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Спиране на звука на разделите</translation> <translation id="9040661932550800571">Да се актуализира ли паролата за <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Достъпът до локални файлове на компютъра ви е деактивиран от администратора ви</translation> <translation id="9042893549633094279">Поверителност и сигурност</translation> @@ -5301,7 +5276,6 @@ <translation id="920045321358709304">Търсене с/ъс <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Опции за заключване на екрана</translation> <translation id="9203398526606335860">&Профилирането е активирано</translation> -<translation id="9203478404496196495">Включване отново на звука на раздела</translation> <translation id="9203904171912129171">Избор на устройство</translation> <translation id="9203962528777363226">Администраторът на това устройство е деактивирал добавянето на нови потребители</translation> <translation id="9213073329713032541">Инсталирането стартира успешно.</translation>
diff --git a/chrome/app/resources/generated_resources_bn.xtb b/chrome/app/resources/generated_resources_bn.xtb index c3b4947..3c6d603 100644 --- a/chrome/app/resources/generated_resources_bn.xtb +++ b/chrome/app/resources/generated_resources_bn.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">ছেড়ে যেতে ESCAPE টিপুন (কেবল নন-অফিশিয়াল বিল্ড)৷</translation> <translation id="1093457606523402488">দৃশ্যমান নেটওয়ার্কগুলি</translation> <translation id="1094607894174825014">এখানে একটি অবৈধ অফসেট সহ পড়া বা লেখার ক্রিয়াকলাপের অনুরোধ করা হয়েছিল:: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">সাইটগুলি আনমিউট করুন</translation> <translation id="1097658378307015415">প্রবেশ করার আগে, <ph name="NETWORK_ID" /> নেটওয়ার্ক সক্রিয় করতে দয়া করে অতিথি রূপে প্রবেশ করুন</translation> <translation id="1103523840287552314">সর্বদা অনুবাদ করুন <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Stop</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">ব্রাউজিং এর ইতিহাস সেভ না করে ওয়েব ব্রাউজ করার জন্য ছদ্মবেশী উইন্ডো ব্যবহার করুন</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" />টি আঙ্গুলের ছাপের সেট আপ</translation> <translation id="1215411991991485844">নতুন পটভূমি অ্যাপ্লিকেশন জোড়া হয়েছে</translation> -<translation id="1216654534877302979">সাইটগুলি মিউট করুন</translation> <translation id="1216659994753476700">আমরা দুঃখিত। আমরা আপনার প্রোফাইল অ্যাক্সেস করতে পারছি না। এই ডিভাইসে সঞ্চিত ফাইল এবং ডেটা হয়ত হারিয়ে গেছে।<ph name="BR" /> <ph name="BR" /> আপনাকে আপনার প্রোফাইল আবার সেট আপ করতে হবে।<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">আপনার Google ড্রাইভ অ্যাকাউন্টে ডেটা সেভ করুন</translation> <translation id="1288037062697528143">সূর্যাস্তের সময় নাইট লাইট নিজে থেকেই চালু হবে</translation> <translation id="1288300545283011870">ভাষ্য প্রপার্টি</translation> -<translation id="1293177648337752319">সাইটটি আনমিউট করুন</translation> <translation id="1293264513303784526">USB-C ডিভাইস (বাঁ পোর্ট)</translation> <translation id="1293556467332435079">ফাইলসমূহ</translation> <translation id="1296497012903089238">শংসাপত্রের প্রকার</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">হোমপেজ হল নতুন ট্যাব পৃষ্ঠা</translation> <translation id="1436671784520050284">সেট-আপ চালিয়ে যান</translation> <translation id="1436784010935106834">সরানো হয়েছে</translation> -<translation id="1438632560381091872">ট্যাবগুলি সশব্দ করুন</translation> <translation id="1442392616396121389">রাউটিং প্রিফিক্স</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" />টি নির্বাচিত হয়েছে</translation> <translation id="1444628761356461360">এই সেটিংটি ডিভাইসের মালিকের দ্বারা <ph name="OWNER_EMAIL" /> পরিচালিত হয়৷</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">আপনি যখন শেষবার পাসওয়ার্ডটি লিখেছিলেন তার পরে অন্য একটি কীবোর্ডে কানেক্ট করা হয়েছিল। এটি আপনার পাসওয়ার্ড চুরি করার চেষ্টা করতে পারে।</translation> <translation id="1567750922576943685">আপনার পরিচয় যাচাই করলে তা আপনার ব্যক্তিগত তথ্য রক্ষা করতে সহায়তা করে</translation> <translation id="1567993339577891801">JavaScript কনসোল</translation> -<translation id="1568067597247500137">সাইটটি মিউট করুন</translation> <translation id="1568323446248056064">প্রদর্শন ডিভাইস সেটিংস খুলুন</translation> <translation id="1572266655485775982">ওয়াই ফাই সক্ষম করুন</translation> <translation id="1572585716423026576">ওয়ালপেপার হিসেবে সেট করুন</translation> @@ -440,7 +435,6 @@ <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="1646982517418478057">এই শংসাপত্রটি এনক্রিপ্ট করতে দয়া করে একটি পাসওয়ার্ড লিখুন</translation> <translation id="164814987133974965">আপনার নির্দেশনার মাধ্যমে একজন ব্যবহারকারী ওয়েবে এক্সপ্লোর করতে পারেন৷ একজন তত্ত্বাবধানে থাকা ব্যবহারকারীর পরিচালক হিসাবে আপনি, বিশেষ ওয়েবসাইটগুলি <ph name="BEGIN_BOLD" />মুঞ্জুরি বা নিষিদ্ধ<ph name="END_BOLD" /> করতে পারেন, @@ -498,7 +492,6 @@ <translation id="1729533290416704613">আপনি Omnibox থেকে সার্চ করলে কোন পৃষ্ঠাটি দেখানো হবে তাও এটি নিয়ন্ত্রণ করে।</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />অ্যাপগুলি সরাতে, সেটিংস > Google Play স্টোর > Android অভিরুচি ম্যানেজ করুন > অ্যাপ বা অ্যাপ্লিকেশন ম্যানেজার বিকল্পে যান। এরপর যে অ্যাপটিকে আনইনস্টল করতে চান তাতে ট্যাপ করুন (অ্যাপটি খোঁজার জন্য আপনাকে ডানদিক বা বাঁদিকে সোয়াইপ করতে হতে পারে)। এরপর আনইনস্টল করুন বা বন্ধ করুন বিকল্পে ট্যাপ করুন।<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">অনুরোধ পাঠানো হচ্ছে...</translation> -<translation id="1732215134274276513">ট্যাবগুলি আনপিন করুন</translation> <translation id="1733383495376208985">আপনার নিজস্ব <ph name="BEGIN_LINK" />সিঙ্ক পাসফ্রেজ<ph name="END_LINK" /> দিয়ে সিঙ্ক করা ডেটা এনক্রিপ্ট করুন। এতে Google Pay-এর পেমেন্ট পদ্ধতি ও ঠিকানা অন্তর্ভুক্ত থাকে না।</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> নিজেকে আপডেট রাখতে হয়ত সক্ষম নয়</translation> <translation id="1736419249208073774">ঘুরে দেখুন</translation> @@ -550,7 +543,6 @@ <translation id="1807938677607439181">সবকটি ফাইল</translation> <translation id="1809734401532861917"><ph name="USER_EMAIL_ADDRESS" /> এ আমার বুকমার্ক, ইতিহাস, পাসওয়ার্ড এবং অন্যান্য সেটিংস যোগ করুন</translation> <translation id="1810764548349082891">কোনো পূর্বরূপ উপলব্ধ নেই</translation> -<translation id="1812631533912615985">ট্যাবগুলি আনপিন করুন</translation> <translation id="1813278315230285598">পরিষেবাসমূহ</translation> <translation id="18139523105317219">EDI পার্টি নাম</translation> <translation id="1815083418640426271">সাধারণ পাঠ্য হিসাবে আটকে দিন </translation> @@ -709,7 +701,6 @@ <translation id="2065405795449409761">স্বয়ংক্রিয় পরীক্ষার সফ্টওয়্যার দ্বারা Chrome নিয়ন্ত্রিত হচ্ছে।</translation> <translation id="2070909990982335904">ডট দিয়ে শুরু নমাগুলি সিস্টেমের জন্য সংরক্ষিত৷ দয়া করে অন্য নাম চয়ন করুন৷</translation> <translation id="2071393345806050157">কোনো স্থানীয় লগ ফাইল নেই।</translation> -<translation id="2074527029802029717">আনপিন ট্যাব</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% ব্যাটারি</translation> <translation id="2075959085554270910">ক্লিক করতে ট্যাপ এবং টেনে আনার জন্য ট্যাপ করার বিকল্প চালু/বন্ধ করতে আপনাকে অনুমতি দেয়</translation> <translation id="2076269580855484719">এই প্লাগইনটি লুকান</translation> @@ -1357,7 +1348,6 @@ <translation id="3045447014237878114">এই সাইটটি নিজে থেকে একাধিক ফাইল ডাউনলোড করেছে</translation> <translation id="3046910703532196514">ওয়েবপৃষ্ঠা, সম্পন্ন</translation> <translation id="304747341537320566">ভাষ্য ইঞ্জিন</translation> -<translation id="304826556400666995">ট্যাবগুলি সশব্দ করুন</translation> <translation id="3053013834507634016">শংসাপত্র কী ব্যবহার</translation> <translation id="3057861065630527966">আপনার ফটো ও ভিডিওগুলির ব্যাকআপ নিন</translation> <translation id="3060379269883947824">'বাছুন ও শুনুন' চালু করুন</translation> @@ -2339,7 +2329,6 @@ <translation id="4628762811416793313">Linux কন্টেনার সেট-আপ সম্পূর্ণ করা যায়নি। আবার চেষ্টা করুন।</translation> <translation id="4628948037717959914">ফটো</translation> <translation id="4631887759990505102">শিল্পী</translation> -<translation id="4632483769545853758">ট্যাব সশব্দ করুন</translation> <translation id="4633003931260532286">এক্সটেনশনের ন্যূনতম <ph name="IMPORT_VERSION" /> ভার্সনের <ph name="IMPORT_NAME" /> প্রয়োজন, কিন্তু শুধুমাত্র <ph name="INSTALLED_VERSION" /> ভার্সন ইনস্টল করা আছে</translation> <translation id="4634771451598206121">আবার প্রবেশ করুন...</translation> <translation id="4635398712689569051">অতিথি ব্যবহারকারীদের জন্য <ph name="PAGE_NAME" /> উপলভ্য নয়।</translation> @@ -2404,7 +2393,6 @@ <translation id="4736292055110123391">আপনার সমস্ত ডিভাইসে বুকমার্ক, পাসওয়ার্ড, ইতিহাস এবং আরও অনেক কিছু সিঙ্ক করুন</translation> <translation id="4737715515457435632">দয়া করে একটি নেটওয়ার্কে সংযোগ করুন</translation> <translation id="473775607612524610">আপডেট করুন</translation> -<translation id="474217410105706308">ট্যাব মিউট করুন</translation> <translation id="4742746985488890273">শেল্ফে পিন করুন</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />অ্যাপ্লিকেশন কীভাবে আপডেট করতে হয় তা জানুন<ph name="END_LINK" /></translation> <translation id="4746351372139058112">বার্তাগুলি</translation> @@ -2629,7 +2617,6 @@ <translation id="5094721898978802975">সহযোগী ন্যাটিভ অ্যাপ্লিকেশানগুলির সাথে যোগাযোগ করুন</translation> <translation id="5097002363526479830">'<ph name="NAME" />': <ph name="DETAILS" /> নেটওয়ার্কে সংযোগ করা গেল না </translation> <translation id="5101042277149003567">সকল বুকমার্ক খুলুন</translation> -<translation id="5105855035535475848">ট্যাবগুলি পিন করুন</translation> <translation id="5108967062857032718">সেটিংস - Android অ্যাপ্লিকেশানগুলি সরান</translation> <translation id="5109044022078737958">মিয়া</translation> <translation id="5111692334209731439">&বুকমার্ক পরিচালক</translation> @@ -2694,7 +2681,6 @@ <translation id="520621735928254154">শংসাপত্রের আমদানি ত্রুটি</translation> <translation id="5209320130288484488">কোনো ডিভাইস খুঁজে পাওয়া যায়নি</translation> <translation id="5209518306177824490">SHA-1 আঙুলের ছাপ</translation> -<translation id="5210365745912300556">ট্যাব বন্ধ করুন</translation> <translation id="5213481667492808996">আপনার '<ph name="NAME" />' ডেটা পরিষেবা ব্যবহারের জন্য প্রস্তুত</translation> <translation id="5213891612754844763">প্রক্সি সেটিংস দেখুন</translation> <translation id="521582610500777512">ফটো বাতিল হয়েছে</translation> @@ -2745,7 +2731,6 @@ <translation id="5272654297705279635">কাস্টম সেটিংস</translation> <translation id="5275352920323889391">কুকুর</translation> <translation id="5275973617553375938">Google ড্রাইভ থেকে উদ্ধার করা ফাইলগুলি</translation> -<translation id="527605719918376753">ট্যাব মিউট করুন</translation> <translation id="527605982717517565">সর্বদা <ph name="HOST" />-এ JavaScript মঞ্জুর করুন</translation> <translation id="5280426389926346830">শর্টকাট তৈরি করবেন?</translation> <translation id="528208740344463258">Android অ্যাপ ডাউনলোড এবং ব্যবহার করার জন্য প্রথমে আপনাকে এই প্রয়োজনীয় আপডেটটি ইনস্টল করা করতে হবে। আপনার <ph name="DEVICE_TYPE" /> আপডেট হওয়ার সময়, আপনি এটি ব্যবহার করতে পারবেন না। ইনস্টলেশন শেষ হওয়ার পরে, আপনার <ph name="DEVICE_TYPE" /> পুনরায় চালু করা হবে।</translation> @@ -2868,7 +2853,6 @@ <translation id="5449551289610225147">অবৈধ পাসওয়ার্ড</translation> <translation id="5449588825071916739">সবকটি ট্যাব বুকমার্ক করুন...</translation> <translation id="5449716055534515760">Close Win&dow</translation> -<translation id="5453029940327926427">ট্যাবগুলি বন্ধ করুন</translation> <translation id="5454166040603940656"><ph name="PROVIDER" /> সহ</translation> <translation id="5457113250005438886">অবৈধ</translation> <translation id="5457459357461771897">আপনার কম্পিউটার থেকে ফটো, সঙ্গীত ও অন্যান্য মিডিয়া পড়ুন এবং মুছুন</translation> @@ -3334,7 +3318,6 @@ <translation id="6122875415561139701">"<ph name="DEVICE_NAME" />" এ লেখার ক্রিয়াকলাপ অনুমোদিত নয়।</translation> <translation id="6124650939968185064">নিম্নলিখিত এক্সটেনশনগুলি এই এক্সটেনশনটির উপর নির্ভর করে:</translation> <translation id="6125479973208104919">দুর্ভাগ্যবশত, আপনাকে এই <ph name="DEVICE_TYPE" /> এ আবার অ্যাকাউন্ট তৈরি করতে হবে।</translation> -<translation id="612596694132302162">সাইটটি আনমিউট করুন</translation> <translation id="6129691635767514872">বেছে নেওয়া ডেটা Chrome ও সিঙ্ক করা ডিভাইস থেকে সরিয়ে ফেলা হয়েছে। আপনার Google অ্যাকাউন্টের অন্যান্য ধরনের ব্রাউজিং ইতিহাস, যেমন বিভিন্ন Google পরিষেবায় করা সার্চ এবং অ্যাক্টিভিটির মতো তথ্য <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> এ সেভ করা থাকতে পারে।</translation> <translation id="6129938384427316298">Netscape শংসাপত্র মন্তব্য</translation> <translation id="6129953537138746214">ব্যবধান</translation> @@ -3538,7 +3521,6 @@ <translation id="6436164536244065364">ওয়েব স্টোর-এ দেখুন</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - অডিও বাজছে</translation> <translation id="6442187272350399447">দুর্দান্ত</translation> -<translation id="6442697326824312960">আনপিন ট্যাব</translation> <translation id="6444070574980481588">তারিখ ও সময় সেট করুন</translation> <translation id="6445450263907939268">এই পরিবর্তনগুলি না চাইলে আপনি আপনার পূর্ববর্তী সেটিংস পুনরুদ্ধার করতে পারেন।</translation> <translation id="6447842834002726250">কুকিজ</translation> @@ -3741,7 +3723,6 @@ <translation id="6770664076092644100">NFC এর মাধ্যমে যাচাই করুন</translation> <translation id="6771503742377376720">একটি শংসাপত্রের কর্তৃপক্ষ</translation> <translation id="6777817260680419853">রিডাইরেক্ট ব্লক করা হয়েছে</translation> -<translation id="6778959797435875428">সাইটগুলি আনমিউট করুন</translation> <translation id="677965093459947883">অতি ক্ষুদ্র</translation> <translation id="6780439250949340171">অন্যান্য সেটিংস পরিচালনা করুন</translation> <translation id="6781284683813954823">ডুডল লিঙ্ক</translation> @@ -4058,7 +4039,6 @@ <translation id="7257666756905341374">আপনি যে ডেটা প্রতিলিপি ও লেপন করেন তা পড়ুন</translation> <translation id="7258697411818564379">আপনার পিন যোগ করা হয়েছে</translation> <translation id="7262004276116528033">এই প্রবেশ করা পরিষেবাটি <ph name="SAML_DOMAIN" /> দ্বারা হোস্ট করা হয়</translation> -<translation id="7268365133021434339">ট্যাবগুলি বন্ধ করুন</translation> <translation id="7268659760406822741">উপলব্ধ পরিষেবাসমূহ</translation> <translation id="7270858098575133036">যখন কোনো সাইট MIDI ডিভাইসগুলি অ্যাক্সেস করার জন্য সিস্টেমের বিশিষ্ট বার্তাগুলি ব্যবহার করতে চায় তখন জিজ্ঞাসা করুন</translation> <translation id="7272674038937250585">কোনও বিবরণ নেই</translation> @@ -4248,7 +4228,6 @@ <translation id="7576032389798113292">৬x৪</translation> <translation id="7576690715254076113">ক্রমসজ্জিত</translation> <translation id="7576976045740938453">ডেমো মোড অ্যাকাউন্ট নিয়ে একটি সমস্যা হয়েছে।</translation> -<translation id="7579149537961810247">সাইটগুলি মিউট করুন</translation> <translation id="7580671184200851182">সব স্পিকারে একই অডিও বাজান (মোনো অডিও)</translation> <translation id="7581462281756524039">একটি পরিষ্কারের টুল</translation> <translation id="7582582252461552277">এই নেটওয়ার্কটিকে অগ্রাধিকার দিন</translation> @@ -4601,7 +4580,6 @@ <translation id="8068253693380742035">প্রবেশ করতে স্পর্শ করুন</translation> <translation id="8069615408251337349">Google ক্লাউড প্রিন্ট</translation> <translation id="8071432093239591881">ছবি হিসেবে প্রিন্ট করুন</translation> -<translation id="8072988827236813198">ট্যাবগুলি পিন করুন</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />অ্যাপ ডেটা এমন যেকোনও ডেটা যা কোনও অ্যাপ (ডেভেলপারের সেটিংসের উপর ভিত্তি করে) সেভ করে রাখে যেমন - পরিচিতি, মেসেজ এবং ফটোর মতো ডেটা।<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />ব্যাক-আপ ডেটা আপনার সন্তানের ড্রাইভ স্টোরেজের কোটার মধ্যে ধরা হবে না।<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />সেটিংস থেকে আপনি এই পরিষেবাটি বন্ধ করতে পারেন।<ph name="END_PARAGRAPH3" /></translation> @@ -4787,7 +4765,6 @@ <translation id="8368859634510605990">&সকল বুকমার্ক খুলুন</translation> <translation id="8371695176452482769">এখনই বলুন</translation> <translation id="8372369524088641025">খারাপ WEP কী</translation> -<translation id="8373553483208508744">ট্যাবগুলি মিউট করুন</translation> <translation id="8378714024927312812">আপনার প্রতিষ্ঠানের দ্বারা ম্যানেজ করা</translation> <translation id="8379878387931047019">এই ওয়েবসাইটটি খুলতে যে নিরাপত্তা কী প্রয়োজন সেটি এই ডিভাইসে কাজ করে না</translation> <translation id="8382913212082956454">&ইমেল ঠিকানা কপি করুন</translation> @@ -4895,7 +4872,6 @@ <translation id="8546930481464505581">টাচ বার কাস্টমাইজ করুন</translation> <translation id="8547013269961688403">ফুলস্ক্রিন ম্যাগনিফায়ার চালু করুন</translation> <translation id="85486688517848470">সবথেকে উপরের-সারির বোতামগুলির আচরণ পরিবর্তন করতে সার্চ বোতাম ধরে থাকুন</translation> -<translation id="855081842937141170">ট্যাব পিন করুন</translation> <translation id="8551388862522347954">লাইসেন্সগুলি</translation> <translation id="8553342806078037065">অন্যান্য ব্যক্তিদের পরিচালনা করুন</translation> <translation id="8554899698005018844">কোনও ভাষা নেই</translation> @@ -5210,7 +5186,6 @@ <translation id="9038430547971207796">পরের বার, আপনার ফোন থেকে নিজের <ph name="DEVICE_TYPE" /> আনলক করতে পারবেন। সেটিংসে গিয়ে Smart Lock বন্ধ করুন।</translation> <translation id="9038649477754266430">পৃষ্ঠা আরও দ্রুত লোড করার জন্য কোনো পূর্বাভাষ পরিষেবা ব্যবহার করুন</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">ট্যাবগুলি মিউট করুন</translation> <translation id="9040661932550800571"><ph name="ORIGIN" />-এর জন্য পাসওয়ার্ড আপডেট করবেন?</translation> <translation id="9041692268811217999">আপনার মেশিনে স্থানীয় ফাইলগুলিতে অ্যাক্সেস আপনার প্রশাসক বন্ধ করেছেন</translation> <translation id="9042893549633094279">গোপনীয়তা এবং নিরাপত্তা</translation> @@ -5308,7 +5283,6 @@ <translation id="920045321358709304"><ph name="SEARCH_ENGINE" /> এ খুঁজুন</translation> <translation id="9201220332032049474">স্ক্রিন লক-এর বিকল্পগুলি</translation> <translation id="9203398526606335860">&প্রোফাইলিং সক্ষমিত</translation> -<translation id="9203478404496196495">ট্যাব সশব্দ করুন</translation> <translation id="9203904171912129171">একটি ডিভাইস বেছে নিন</translation> <translation id="9203962528777363226">এই ডিভাইসের প্রশাসক নতুন ব্যবহারকারী জোড়া অক্ষম করেছে</translation> <translation id="9213073329713032541">ইনস্টলেশন চালু হয়েছে।</translation>
diff --git a/chrome/app/resources/generated_resources_ca.xtb b/chrome/app/resources/generated_resources_ca.xtb index a0cf31c..1679c0d 100644 --- a/chrome/app/resources/generated_resources_ca.xtb +++ b/chrome/app/resources/generated_resources_ca.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Premeu ESCAPE per ometre (només compilacions no oficials).</translation> <translation id="1093457606523402488">Xarxes visibles:</translation> <translation id="1094607894174825014">S'ha sol·licitat una operació de lectura o escriptura amb un decalatge no vàlid a <ph name="DEVICE_NAME" />.</translation> -<translation id="109758035718544977">Deixa de silenciar els llocs web</translation> <translation id="1097658378307015415">Abans d'iniciar la sessió amb el vostre usuari, entreu com a convidat per activar la xarxa <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Tradueix sempre el text en <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Atura</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Utilitza el web sense desar l'historial de navegació amb una finestra d'incògnit</translation> <translation id="1213037489357051291">Nombre d'empremtes digitals configurades: <ph name="NUM_FINGERPRINTS" /></translation> <translation id="1215411991991485844">S'ha afegit una aplicació en segon pla nova</translation> -<translation id="1216654534877302979">Silencia els llocs web</translation> <translation id="1216659994753476700">No podem accedir al vostre perfil. És possible que els fitxers i les dades emmagatzemades en aquest dispositiu s'hagin perdut.<ph name="BR" /> <ph name="BR" /> Heu de tornar a configurar el perfil.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Emmagatzema les dades al compte de Google Drive</translation> <translation id="1288037062697528143">La funció Llum nocturna s'activarà automàticament quan es pongui el sol</translation> <translation id="1288300545283011870">Propietats de la veu</translation> -<translation id="1293177648337752319">Deixa de silenciar el lloc web</translation> <translation id="1293264513303784526">Dispositiu USB-C (port esquerre)</translation> <translation id="1293556467332435079">Fitxers</translation> <translation id="1296497012903089238">Tipus de certificat</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">La pàgina d'inici és la pàgina Pestanya nova</translation> <translation id="1436671784520050284">Continua amb la configuració</translation> <translation id="1436784010935106834">Eliminat</translation> -<translation id="1438632560381091872">Deixa de silenciar les pestanyes</translation> <translation id="1442392616396121389">Prefix d'encaminament</translation> <translation id="144283815522798837">Elements seleccionats: <ph name="NUMBER_OF_ITEMS_SELECTED" /></translation> <translation id="1444628761356461360">Aquesta configuració està gestionada pel propietari del dispositiu, <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">S'ha connectat un altre teclat des de la darrera vegada que vas introduir la contrasenya. Pot ser que estigui provant de robar-te les combinacions de tecles.</translation> <translation id="1567750922576943685">Verificar la teva identitat t'ajuda a protegir la informació personal</translation> <translation id="1567993339577891801">Consola de JavaScript</translation> -<translation id="1568067597247500137">Silencia el lloc web</translation> <translation id="1568323446248056064">Obre la configuració de la pantalla</translation> <translation id="1572266655485775982">Activa la Wi-Fi</translation> <translation id="1572585716423026576">Defineix com a fons de pantalla</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">Signatura d'ECDSA X9.62 amb SHA-1</translation> <translation id="1644574205037202324">Historial</translation> <translation id="1645516838734033527">Per mantenir la seguretat a <ph name="DEVICE_TYPE" />, Smart Lock requereix que el telèfon tingui configurat un bloqueig de pantalla.</translation> -<translation id="1646102270785326155">Tots els fitxers i totes les dades locals associats amb aquest usuari se suprimiran definitivament quan aquest usuari se suprimeixi. De totes maneres, després $1 encara podrà iniciar la sessió.</translation> <translation id="1646982517418478057">Introdueix una contrasenya per encriptar aquest certificat</translation> <translation id="164814987133974965">Els usuaris supervisats poden explorar el web amb la vostra orientació. Com a administrador d'un usuari supervisat, podeu fer les accions següents: <ph name="BEGIN_BOLD" />permetre o prohibir<ph name="END_BOLD" /> determinats llocs web, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">També controla la pàgina que es mostra quan feu una cerca des de l'omnibox.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Per suprimir una aplicació, ves a Configuració > Google Play Store > Gestiona les preferències d'Android > Aplicacions o Gestor d'aplicacions. A continuació, toca l'aplicació que vulguis desinstal·lar (és possible que hagis de lliscar cap a la dreta o cap a l'esquerra per trobar-la). Tot seguit, toca Desinstal·la o Desactiva.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Enviant sol·licitud....</translation> -<translation id="1732215134274276513">No fixis les pestanyes</translation> <translation id="1733383495376208985">Encripta les dades sincronitzades amb la teva <ph name="BEGIN_LINK" />frase de contrasenya de sincronització<ph name="END_LINK" />. No inclou les formes de pagament ni les adreces de Google Pay.</translation> <translation id="1734824808160898225">És possible que <ph name="PRODUCT_NAME" /> no pugui actualitzar-se tot sol</translation> <translation id="1736419249208073774">Explora</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Tots els fitxers</translation> <translation id="1809734401532861917">Afegeix les adreces d'interès, l'historial, les contrasenyes i altres opcions de configuració a <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">No hi ha cap previsualització disponible</translation> -<translation id="1812631533912615985">No fixis les pestanyes</translation> <translation id="1813278315230285598">Serveis</translation> <translation id="18139523105317219">Nom de la part EDI</translation> <translation id="1815083418640426271">Enganxa com a text sense format</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Un programari de prova automatitzat està controlant Chrome.</translation> <translation id="2070909990982335904">Els noms que comencen amb punt estan reservats per al sistema. Trieu un altre nom.</translation> <translation id="2071393345806050157">No hi ha cap fitxer de registre local.</translation> -<translation id="2074527029802029717">No fixis la pestanya</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% de bateria</translation> <translation id="2075959085554270910">Et permet activar o desactivar les opcions de tocar per fer clic i de tocar i arrossegar</translation> <translation id="2076269580855484719">Amaga aquest connector</translation> @@ -773,6 +764,7 @@ <translation id="215753907730220065">Surt de la pantalla completa</translation> <translation id="2157875535253991059">Ara aquesta pàgina es mostra a pantalla completa.</translation> <translation id="216169395504480358">Afegeix una Wi-Fi...</translation> +<translation id="2162155940152307086">La sincronització començarà quan surtis de la configuració de la sincronització</translation> <translation id="2163470535490402084">Connecteu-vos a Internet per iniciar la sessió al dispositiu <ph name="DEVICE_TYPE" />.</translation> <translation id="2166369534954157698">L'àgil guineu marró salta per sobre del gos mandrós</translation> <translation id="2169062631698640254">Inicia la sessió de tota manera</translation> @@ -783,6 +775,7 @@ <translation id="2178098616815594724">El connector <ph name="PEPPER_PLUGIN_NAME" /> del lloc web <ph name="PEPPER_PLUGIN_DOMAIN" /> vol accedir a l'ordinador</translation> <translation id="2178614541317717477">Compromís de CA</translation> <translation id="218070003709087997">Utilitza un número per indicar quantes còpies vols imprimir (entre 1 i 999).</translation> +<translation id="2182253583899676504">Allò que escriguis als camps de text s'enviarà a Google.</translation> <translation id="2184515124301515068">Deixa que Chrome triï quan poden reproduir so els llocs web (opció recomanada)</translation> <translation id="2187895286714876935">Error d'importació del certificat del servidor</translation> <translation id="2187906491731510095">S'han actualitzat les extensions</translation> @@ -794,7 +787,9 @@ <translation id="2192505247865591433">De:</translation> <translation id="2193365732679659387">Configuració de confiança</translation> <translation id="2195729137168608510">Protecció del correu electrònic</translation> +<translation id="2198757192731523470">És possible que Google utilitzi el teu historial per personalitzar la Cerca, els anuncis i altres serveis de Google.</translation> <translation id="2199298570273670671">Error</translation> +<translation id="2199719347983604670">Dades de la sincronització de Chrome</translation> <translation id="2200094388063410062">Correu electrònic</translation> <translation id="2200356397587687044">Chrome necessita permís per continuar</translation> <translation id="2200603218210188859">Preferències de dispositius USB</translation> @@ -1250,6 +1245,7 @@ <translation id="2889064240420137087">Obre l'enllaç amb...</translation> <translation id="2889925978073739256">Continua bloquejant els connectors de fora de la zona de proves</translation> <translation id="2893168226686371498">Navegador predeterminat</translation> +<translation id="2895734772884435517">Pots personalitzar aquestes opcions de configuració en qualsevol moment.</translation> <translation id="289644616180464099">La targeta SIM està bloquejada</translation> <translation id="289695669188700754">Identificador de clau: <ph name="KEY_ID" /></translation> <translation id="2897878306272793870">Confirmes que vols obrir <ph name="TAB_COUNT" /> pestanyes?</translation> @@ -1350,7 +1346,6 @@ <translation id="3045447014237878114">Aquest lloc web ha baixat diversos fitxers automàticament</translation> <translation id="3046910703532196514">Pàgina web completa</translation> <translation id="304747341537320566">Motors de veu</translation> -<translation id="304826556400666995">Deixa de silenciar les pestanyes</translation> <translation id="3053013834507634016">Ús de claus de certificat</translation> <translation id="3057861065630527966">Crea una còpia de seguretat de les fotos i dels vídeos</translation> <translation id="3060379269883947824">Activa Escolta la selecció</translation> @@ -1718,6 +1713,7 @@ <translation id="3636096452488277381">Hola, <ph name="USER_GIVEN_NAME" />.</translation> <translation id="3636766455281737684"><ph name="PERCENTAGE" />% - Temps restant: <ph name="TIME" /></translation> <translation id="3637682276779847508">Si no introdueixes el número PUK correcte, la targeta SIM es desactivarà de manera definitiva.</translation> +<translation id="363863692969456324">Corregeix els errors d'ortografia amb el corrector ortogràfic millorat</translation> <translation id="3640214691812501263">Voleu afegir l'extensió <ph name="EXTENSION_NAME" /> per a <ph name="USER_NAME" />?</translation> <translation id="3644896802912593514">Amplada</translation> <translation id="3645372836428131288">Mou el dit lleugerament perquè es pugui capturar una altra part de l'empremta digital.</translation> @@ -2149,6 +2145,7 @@ <translation id="4310139701823742692">El format del fitxer PPD és incorrecte. Revisa'l i torna-ho a provar.</translation> <translation id="431076611119798497">&Detalls</translation> <translation id="4312866146174492540">Bloqueja (opció predeterminada)</translation> +<translation id="4314815835985389558">Gestiona la sincronització</translation> <translation id="4316850752623536204">Lloc web per a desenvolupadors</translation> <translation id="4320177379694898372">No hi ha connexió a Internet</translation> <translation id="4320948194796820126">Afegeix un marcador al teu correu electrònic</translation> @@ -2228,6 +2225,7 @@ <translation id="4450974146388585462">Diagnòstic</translation> <translation id="4451757071857432900">Anuncis bloquejats als llocs web que mostren publicitat intrusiva o enganyosa (opció recomanada)</translation> <translation id="4453946976636652378">Cerca <ph name="SEARCH_ENGINE_NAME" /> o escriu un URL</translation> +<translation id="4461835665417498653">Envia a Google algunes dades del sistema i contingut de les pàgines de manera anònima.</translation> <translation id="4462159676511157176">Servidors de noms personalitzats</translation> <translation id="4467101674048705704">Desplega <ph name="FOLDER_NAME" /></translation> <translation id="4469477701382819144">Anuncis bloquejats als llocs web que mostren publicitat intrusiva o enganyosa</translation> @@ -2331,7 +2329,6 @@ <translation id="4628762811416793313">La configuració del contenidor de Linux no s'ha completat. Torna-ho a provar.</translation> <translation id="4628948037717959914">Foto</translation> <translation id="4631887759990505102">Artista</translation> -<translation id="4632483769545853758">Activar el so de la pestanya</translation> <translation id="4633003931260532286">L'extensió requereix <ph name="IMPORT_NAME" /> amb <ph name="IMPORT_VERSION" /> com a versió mínima, però només hi ha instal·lada la versió <ph name="INSTALLED_VERSION" /></translation> <translation id="4634771451598206121">Torna a iniciar la sessió...</translation> <translation id="4635398712689569051">La pàgina <ph name="PAGE_NAME" /> no està disponible per als usuaris convidats.</translation> @@ -2393,9 +2390,9 @@ <translation id="4735265153267957659">Introdueix la contrasenya per activar Smart Lock. La propera vegada, el telèfon desbloquejarà <ph name="DEVICE_TYPE" />. Pots desactivar Smart Lock des de Configuració.</translation> <translation id="473546211690256853"><ph name="DOMAIN" /> gestiona aquest compte.</translation> <translation id="4735803855089279419">El sistema no ha pogut determinar els identificadors d'aquest dispositiu.</translation> +<translation id="4736292055110123391">Sincronitza les adreces d'interès, les contrasenyes, l'historial i altres elements en tots els dispositius</translation> <translation id="4737715515457435632">Connecteu-vos a una xarxa</translation> <translation id="473775607612524610">Actualitza</translation> -<translation id="474217410105706308">Silenciar la pestanya</translation> <translation id="4742746985488890273">Fixa al prestatge</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Obtén informació sobre com s'actualitzen les aplicacions<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Missatges</translation> @@ -2620,7 +2617,6 @@ <translation id="5094721898978802975">Comunicació amb aplicacions natives cooperatives</translation> <translation id="5097002363526479830">S'ha produït un error en connectar amb la xarxa "<ph name="NAME" />": <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Obre totes les adreces d'interès</translation> -<translation id="5105855035535475848">Fixa les pestanyes</translation> <translation id="5108967062857032718">Configuració: suprimeix les aplicacions per a Android</translation> <translation id="5109044022078737958">Atleta</translation> <translation id="5111692334209731439">&Gestor d'adreces d'interès</translation> @@ -2685,7 +2681,6 @@ <translation id="520621735928254154">S'ha produït un error en importar el certificat</translation> <translation id="5209320130288484488">No s'ha trobat cap dispositiu</translation> <translation id="5209518306177824490">Empremta SHA-1</translation> -<translation id="5210365745912300556">Tanca la pestanya</translation> <translation id="5213481667492808996">Ja pots utilitzar el servei de dades <ph name="NAME" /></translation> <translation id="5213891612754844763">Mostra la configuració del servidor intermediari</translation> <translation id="521582610500777512">La foto s'ha descartat.</translation> @@ -2735,9 +2730,9 @@ <translation id="5266113311903163739">Error d'importació de l'entitat emissora de certificats</translation> <translation id="5269977353971873915">Error d'impressió</translation> <translation id="5270167208902136840">Mostra <ph name="NUMBER_OF_MORE_APPS" /> aplicacions més</translation> +<translation id="5272654297705279635">Configuració personalitzada</translation> <translation id="5275352920323889391">Gos</translation> <translation id="5275973617553375938">Fitxers recuperats de Google Drive</translation> -<translation id="527605719918376753">Silencia la pestanya</translation> <translation id="527605982717517565">Permet sempre JavaScript a <ph name="HOST" /></translation> <translation id="5280426389926346830">Vols crear una drecera?</translation> <translation id="528208740344463258">Per baixar i utilitzar les aplicacions d'Android, primer has d'instal·lar aquesta actualització obligatòria. Mentre el dispositiu <ph name="DEVICE_TYPE" /> s'estigui actualitzant, no el podràs fer servir. Un cop finalitzada la instal·lació, <ph name="DEVICE_TYPE" /> es reiniciarà.</translation> @@ -2860,7 +2855,6 @@ <translation id="5449551289610225147">La contrasenya no és vàlida</translation> <translation id="5449588825071916739">Afegeix totes les pestanyes a les adreces d'interès</translation> <translation id="5449716055534515760">Tanca la &finestra</translation> -<translation id="5453029940327926427">Tanca les pestanyes</translation> <translation id="5454166040603940656">amb <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">No vàlides</translation> <translation id="5457459357461771897">Llegeix i suprimeix fotos, música i altres elements multimèdia de l'ordinador</translation> @@ -3326,7 +3320,6 @@ <translation id="6122875415561139701">L'operació d'escriptura no es permet a <ph name="DEVICE_NAME" />.</translation> <translation id="6124650939968185064">D'aquesta extensió en depenen les extensions següents:</translation> <translation id="6125479973208104919">Cal que tornis a afegir el teu compte en aquest <ph name="DEVICE_TYPE" />.</translation> -<translation id="612596694132302162">Deixa de silenciar el lloc web</translation> <translation id="6129691635767514872">Les dades seleccionades s'han suprimit de Chrome i dels dispositius sincronitzats. És possible que el teu compte de Google tingui altres formes de l'historial de navegació, com ara les cerques i l'activitat d'altres serveis de Google a <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Comentari de certificat de Netscape</translation> <translation id="6129953537138746214">Espai</translation> @@ -3529,7 +3522,6 @@ <translation id="6436164536244065364">Mostra-ho a Web Store</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" />: s'està reproduint àudio</translation> <translation id="6442187272350399447">Content</translation> -<translation id="6442697326824312960">No fixis la pestanya</translation> <translation id="6444070574980481588">Defineix la data i l'hora</translation> <translation id="6445450263907939268">Si no volíeu aplicar aquests canvis, podeu restaurar la configuració anterior.</translation> <translation id="6447842834002726250">Galetes</translation> @@ -3732,7 +3724,6 @@ <translation id="6770664076092644100">Verifica la teva identitat per NFC</translation> <translation id="6771503742377376720">És una entitat emissora de certificats</translation> <translation id="6777817260680419853">S'ha bloquejat la redirecció</translation> -<translation id="6778959797435875428">Deixa de silenciar els llocs web</translation> <translation id="677965093459947883">Molt petita</translation> <translation id="6780439250949340171">gestiona una altra configuració</translation> <translation id="6781284683813954823">Enllaç al doodle</translation> @@ -4049,7 +4040,6 @@ <translation id="7257666756905341374">Llegeix les dades que es copiïn i s'enganxin</translation> <translation id="7258697411818564379">S'ha afegit el PIN</translation> <translation id="7262004276116528033">Aquest servei d'inici de sessió s'allotja a <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Tanca les pestanyes</translation> <translation id="7268659760406822741">Serveis disponibles</translation> <translation id="7270858098575133036">Pregunta'm quan un lloc vulgui utilitzar els missatges exclusius del sistema per accedir a dispositius MIDI</translation> <translation id="7272674038937250585">No s'ha proporcionat cap descripció</translation> @@ -4237,7 +4227,6 @@ <translation id="7576032389798113292">6 x 4</translation> <translation id="7576690715254076113">Intercala</translation> <translation id="7576976045740938453">S'ha produït un problema amb el compte del mode de demostració.</translation> -<translation id="7579149537961810247">Silencia els llocs web</translation> <translation id="7580671184200851182">Reprodueix el mateix àudio per tots els altaveus (àudio mono)</translation> <translation id="7581462281756524039">Eina per netejar</translation> <translation id="7582582252461552277">Estableix aquesta xarxa com a preferida</translation> @@ -4591,7 +4580,6 @@ <translation id="8068253693380742035">Toca per iniciar la sessió</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Imprimeix com a imatge</translation> -<translation id="8072988827236813198">Fixa les pestanyes</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Les dades de les aplicacions poden ser qualsevol informació que hagi desat una aplicació (en funció de la configuració del desenvolupador), com ara els contactes, els missatges i les fotos.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Les dades de les còpies de seguretat no ocupen espai de la quota d'emmagatzematge de Drive del teu fill.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Pots desactivar aquest servei a Configuració.<ph name="END_PARAGRAPH3" /></translation> @@ -4776,7 +4764,6 @@ <translation id="8368859634510605990">&Obre totes les adreces d'interès</translation> <translation id="8371695176452482769">Parla ara</translation> <translation id="8372369524088641025">Clau WEP no vàlida</translation> -<translation id="8373553483208508744">Silencia les pestanyes</translation> <translation id="8378714024927312812">Gestionat per la teva organització</translation> <translation id="8379878387931047019">Aquest dispositiu no admet el tipus de clau de seguretat sol·licitat per aquest lloc web</translation> <translation id="8382913212082956454">Copia l'&adreça electrònica</translation> @@ -4884,7 +4871,6 @@ <translation id="8546930481464505581">Personalitza la barra tàctil</translation> <translation id="8547013269961688403">Activa la lupa de pantalla completa</translation> <translation id="85486688517848470">Mantén premuda la tecla de cerca per canviar el comportament de les tecles de la fila superior</translation> -<translation id="855081842937141170">Fixa la pestanya</translation> <translation id="8551388862522347954">Llicències</translation> <translation id="8553342806078037065">Gestiona altres usuaris</translation> <translation id="8554899698005018844">Cap idioma</translation> @@ -4914,6 +4900,7 @@ <translation id="8598453409908276158">S'ha bloquejat l'accés al connector de fora de la zona de proves</translation> <translation id="8601206103050338563">Autenticació de client WWW de TLS</translation> <translation id="8602851771975208551">Un altre programa de l'ordinador ha afegit una aplicació que pot canviar el funcionament de Chrome.</translation> +<translation id="8604763363205185560">Ajuda a millorar Chrome i la seva seguretat</translation> <translation id="8605428685123651449">Memòria SQLite</translation> <translation id="8606726445206553943">Utilitzar els dispositius MIDI</translation> <translation id="8609465669617005112">Desplaça cap amunt</translation> @@ -5198,7 +5185,6 @@ <translation id="9038430547971207796">La propera vegada, el telèfon desbloquejarà <ph name="DEVICE_TYPE" />. Desactiva Smart Lock a Configuració.</translation> <translation id="9038649477754266430">Utilitza un servei de predicció per poder carregar les pàgines més ràpidament</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Silenciar les pestanyes</translation> <translation id="9040661932550800571">Vols actualitzar la contrasenya per a <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">L'administrador ha desactivat l'accés als fitxers locals de l'ordinador</translation> <translation id="9042893549633094279">Privadesa i seguretat</translation> @@ -5296,7 +5282,6 @@ <translation id="920045321358709304">Cerca <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Opcions de bloqueig de pantalla</translation> <translation id="9203398526606335860">Creació de &perfils activada</translation> -<translation id="9203478404496196495">Activa el so de la pestanya</translation> <translation id="9203904171912129171">Selecciona un dispositiu</translation> <translation id="9203962528777363226">L'administrador d'aquest dispositiu ha desactivat la possibilitat d'afegir-hi usuaris nous</translation> <translation id="9213073329713032541">La instal·lació s'ha iniciat.</translation>
diff --git a/chrome/app/resources/generated_resources_cs.xtb b/chrome/app/resources/generated_resources_cs.xtb index 54f047d8..7e4c9ff2 100644 --- a/chrome/app/resources/generated_resources_cs.xtb +++ b/chrome/app/resources/generated_resources_cs.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Akci přeskočíte stisknutím klávesy Esc (pouze neoficiální sestavení).</translation> <translation id="1093457606523402488">Viditelné sítě:</translation> <translation id="1094607894174825014">Na zařízení <ph name="DEVICE_NAME" /> byla požadována operace čtení nebo zápisu s neplatným odstupem.</translation> -<translation id="109758035718544977">Zapnout zvuk webů</translation> <translation id="1097658378307015415">Chcete-li aktivovat síť <ph name="NETWORK_ID" />, vstupte prosím před přihlášením jako host</translation> <translation id="1103523840287552314">Vždy překládat jazyk <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Zastavit</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Pomocí anonymního okna můžete web používat bez ukládání historie procházení</translation> <translation id="1213037489357051291">Nastavení otisků prstu: celkem <ph name="NUM_FINGERPRINTS" /></translation> <translation id="1215411991991485844">Byla přidána nová aplikace na pozadí</translation> -<translation id="1216654534877302979">Ztlumit weby</translation> <translation id="1216659994753476700">Je nám líto, ale k vašemu profilu nemáme přístup. Soubory a data uložená v tomto zařízení mohla být ztracena.<ph name="BR" /> <ph name="BR" /> Profil bude třeba znovu nastavit.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Ukládat údaje v účtu na Disku Google</translation> <translation id="1288037062697528143">Noční režim se zapne automaticky za soumraku</translation> <translation id="1288300545283011870">Vlastnosti řeči</translation> -<translation id="1293177648337752319">Zapnout zvuk webu</translation> <translation id="1293264513303784526">Zařízení USB Type-C (levý port)</translation> <translation id="1293556467332435079">Soubory</translation> <translation id="1296497012903089238">Typ certifikátu</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Domovská stránka je stránka nové karty</translation> <translation id="1436671784520050284">Pokračovat v nastavování</translation> <translation id="1436784010935106834">Odebráno</translation> -<translation id="1438632560381091872">Zapnout zvuk karet</translation> <translation id="1442392616396121389">Předpona směrování</translation> <translation id="144283815522798837">Vybrané položky: <ph name="NUMBER_OF_ITEMS_SELECTED" /></translation> <translation id="1444628761356461360">Toto nastavení spravuje vlastník zařízení, <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Od minulého zadání hesla byla připojena jiná klávesnice. Je možné, že se pokouší odcizit vaše stisknutí kláves.</translation> <translation id="1567750922576943685">Ověření vaší identity pomáhá ochránit vaše osobní údaje</translation> <translation id="1567993339577891801">Konzole JavaScriptu</translation> -<translation id="1568067597247500137">Ztlumit web</translation> <translation id="1568323446248056064">Otevřít nastavení displeje</translation> <translation id="1572266655485775982">Aktivovat Wi-Fi</translation> <translation id="1572585716423026576">Nastavit jako tapetu</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">Podpis X9.62 ECDSA s SHA-1</translation> <translation id="1644574205037202324">Historie</translation> <translation id="1645516838734033527">Smart Lock z důvodu zajištění bezpečnosti zařízení <ph name="DEVICE_TYPE" /> vyžaduje, aby byl v telefonu nastaven zámek obrazovky.</translation> -<translation id="1646102270785326155">Po odebrání tohoto uživatele budou trvale smazány všechny soubory a místní data, která jsou k němu přiřazena. $1 se bude moci později přihlásit.</translation> <translation id="1646982517418478057">Zadejte heslo k zašifrování tohoto certifikátu</translation> <translation id="164814987133974965">Dozorovaný uživatel si může prohlížet web podle vašich pokynů. Jako správce dozorovaného uživatele můžete <ph name="BEGIN_BOLD" />povolit nebo zakázat<ph name="END_BOLD" /> konkrétní weby, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Také řídí, která stránka se zobrazí, když budete vyhledávat v omniboxu.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Chcete-li odstranit aplikace, přejděte do Nastavení > Obchod Google Play > Spravovat nastavení aplikací Android > Aplikace nebo Správce aplikací. Poté klepněte na aplikaci, kterou chcete odinstalovat (je možné, že aplikacemi bude třeba listovat doprava či doleva). Následně klepněte na Odinstalovat nebo Deaktivovat.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Zasílání požadavku</translation> -<translation id="1732215134274276513">Odepnout karty</translation> <translation id="1733383495376208985">Šifrovat synchronizovaná data pomocí vlastní <ph name="BEGIN_LINK" />heslové fráze pro synchronizaci<ph name="END_LINK" />. Toto šifrování se nevztahuje na platební metody a adresy z Google Pay.</translation> <translation id="1734824808160898225">Je možné, že se <ph name="PRODUCT_NAME" /> nebude moci aktualizovat</translation> <translation id="1736419249208073774">Prozkoumat</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Všechny soubory</translation> <translation id="1809734401532861917">Přidejte mé záložky, historii, hesla a další nastavení do účtu <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Náhled není k dispozici</translation> -<translation id="1812631533912615985">Odepnout karty</translation> <translation id="1813278315230285598">Služby</translation> <translation id="18139523105317219">Název strany EDI</translation> <translation id="1815083418640426271">Vložit jako prostý text</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chrome je právě kontrolován pomocí automatického testovacího softwaru.</translation> <translation id="2070909990982335904">Názvy začínající tečkou jsou vyhrazeny pro systém. Zvolte prosím jiný název.</translation> <translation id="2071393345806050157">Žádný místní soubor protokolu není k dispozici.</translation> -<translation id="2074527029802029717">Odepnout kartu</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" /> % baterie</translation> <translation id="2075959085554270910">Umožňuje zapnout a vypnout funkci kliknutí klepnutím a přetahování klepnutím</translation> <translation id="2076269580855484719">Skrýt tento plugin</translation> @@ -1351,7 +1342,6 @@ <translation id="3045447014237878114">Tento web automaticky stáhl několik souborů</translation> <translation id="3046910703532196514">Webová stránka, úplná</translation> <translation id="304747341537320566">Moduly převodu textu na řeč</translation> -<translation id="304826556400666995">Zapnout zvuk karet</translation> <translation id="3053013834507634016">Použití klíče certifikátu</translation> <translation id="3057861065630527966">Zálohovat fotky a videa</translation> <translation id="3060379269883947824">Zapnout poslech vybraného textu</translation> @@ -2331,7 +2321,6 @@ <translation id="4628762811416793313">Nastavení kontejneru systému Linux nebylo dokončeno. Zkuste to znovu.</translation> <translation id="4628948037717959914">Fotka</translation> <translation id="4631887759990505102">Interpret</translation> -<translation id="4632483769545853758">Zapnout zvuk karty</translation> <translation id="4633003931260532286">Rozšíření vyžaduje rozhraní <ph name="IMPORT_NAME" /> s minimální verzí <ph name="IMPORT_VERSION" />, máte však nainstalovanou pouze verzi <ph name="INSTALLED_VERSION" /></translation> <translation id="4634771451598206121">Znovu přihlásit...</translation> <translation id="4635398712689569051">Stránka <ph name="PAGE_NAME" /> hostům není k dispozici.</translation> @@ -2395,7 +2384,6 @@ <translation id="4735803855089279419">Systému se nepodařilo zjistit identifikátory tohoto zařízení.</translation> <translation id="4737715515457435632">Připojte se prosím k síti</translation> <translation id="473775607612524610">Aktualizovat</translation> -<translation id="474217410105706308">Vypnout zvuk karty</translation> <translation id="4742746985488890273">Připnout k poličce</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Přečtěte si, jak aktualizovat aplikace<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Zprávy</translation> @@ -2620,7 +2608,6 @@ <translation id="5094721898978802975">Komunikovat se spolupracujícími nativními aplikacemi</translation> <translation id="5097002363526479830">Připojení k síti <ph name="NAME" /> se nezdařilo: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Otevřít všechny záložky</translation> -<translation id="5105855035535475848">Připnout karty</translation> <translation id="5108967062857032718">Nastavení – odstranit aplikace Android</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">&Správce záložek</translation> @@ -2685,7 +2672,6 @@ <translation id="520621735928254154">Chyba při importu certifikátu</translation> <translation id="5209320130288484488">Nebyla nalezena žádná zařízení</translation> <translation id="5209518306177824490">Digitální otisk SHA-1</translation> -<translation id="5210365745912300556">Zavřít kartu</translation> <translation id="5213481667492808996">Datová služba <ph name="NAME" /> je připravena k použití</translation> <translation id="5213891612754844763">Zobrazit nastavení proxy serveru</translation> <translation id="521582610500777512">Fotografie byla zahozena</translation> @@ -2735,7 +2721,6 @@ <translation id="5270167208902136840">Zobrazit další aplikace (<ph name="NUMBER_OF_MORE_APPS" />)</translation> <translation id="5275352920323889391">Pes</translation> <translation id="5275973617553375938">Obnovené soubory z Disku Google</translation> -<translation id="527605719918376753">Vypnout zvuk karty</translation> <translation id="527605982717517565">Vždy povolovat JavaScript z webu <ph name="HOST" /></translation> <translation id="5280426389926346830">Vytvořit zástupce?</translation> <translation id="528208740344463258">Abyste mohli stahovat a používat aplikace pro Android, nejdříve musíte nainstalovat tuto povinnou aktualizaci. <ph name="DEVICE_TYPE" /> během aktualizace nelze používat. Po dokončení instalace se <ph name="DEVICE_TYPE" /> restartuje.</translation> @@ -2858,7 +2843,6 @@ <translation id="5449551289610225147">Neplatné heslo</translation> <translation id="5449588825071916739">Přidat do záložek všechny karty</translation> <translation id="5449716055534515760">Zavřít okno</translation> -<translation id="5453029940327926427">Zavřít karty</translation> <translation id="5454166040603940656">(<ph name="PROVIDER" />)</translation> <translation id="5457113250005438886">Neplatné</translation> <translation id="5457459357461771897">Číst a mazat fotografie, hudbu a další média z počítače</translation> @@ -3323,7 +3307,6 @@ <translation id="6122875415561139701">Operace zápisu v zařízení <ph name="DEVICE_NAME" /> není povolena.</translation> <translation id="6124650939968185064">Na tomto rozšíření závisejí následující rozšíření:</translation> <translation id="6125479973208104919">Do zařízení <ph name="DEVICE_TYPE" /> je nutné znovu přidat účet.</translation> -<translation id="612596694132302162">Zapnout zvuk webu</translation> <translation id="6129691635767514872">Vybraná data byla z Chromu a synchronizovaných zařízení odstraněna. Na stránce <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> mohou být k dispozici další druhy historie prohlížení zaznamenané ve vašem účtu Google, například vyhledávací dotazy a aktivita z ostatních služeb Google.</translation> <translation id="6129938384427316298">Komentář certifikátu Netscape</translation> <translation id="6129953537138746214">Mezera</translation> @@ -3526,7 +3509,6 @@ <translation id="6436164536244065364">Zobrazit v Internetovém obchodu</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – přehrává se zvuk</translation> <translation id="6442187272350399447">Paráda</translation> -<translation id="6442697326824312960">Odepnout kartu</translation> <translation id="6444070574980481588">Nastavení data a času</translation> <translation id="6445450263907939268">Pokud jste tyto změny provádět nechtěli, můžete obnovit svá předchozí nastavení.</translation> <translation id="6447842834002726250">Soubory cookie</translation> @@ -3729,7 +3711,6 @@ <translation id="6770664076092644100">Ověřit přes NFC</translation> <translation id="6771503742377376720">Je certifikační autorita</translation> <translation id="6777817260680419853">Bylo zablokováno přesměrování</translation> -<translation id="6778959797435875428">Zapnout zvuk webů</translation> <translation id="677965093459947883">Velmi malé</translation> <translation id="6780439250949340171">spravovat jiná nastavení</translation> <translation id="6781284683813954823">Odkaz na sváteční logo</translation> @@ -4046,7 +4027,6 @@ <translation id="7257666756905341374">Číst data, která kopírujete a vkládáte</translation> <translation id="7258697411818564379">PIN byl přidán</translation> <translation id="7262004276116528033">Přihlašovací služba je hostována doménou <ph name="SAML_DOMAIN" />.</translation> -<translation id="7268365133021434339">Zavřít karty</translation> <translation id="7268659760406822741">Dostupné služby</translation> <translation id="7270858098575133036">Zeptat se, když chce web využít exkluzivní zprávy systému pro přístup k zařízením MIDI</translation> <translation id="7272674038937250585">K dispozici není žádný popis</translation> @@ -4234,7 +4214,6 @@ <translation id="7576032389798113292">6:4</translation> <translation id="7576690715254076113">Kompletovat</translation> <translation id="7576976045740938453">Došlo k problému s účtem pro ukázkový režim.</translation> -<translation id="7579149537961810247">Ztlumit weby</translation> <translation id="7580671184200851182">Přehrávat ve všech reproduktorech stejný zvuk (mono)</translation> <translation id="7581462281756524039">Nástroj na vyčištění</translation> <translation id="7582582252461552277">Preferovat tuto síť</translation> @@ -4588,7 +4567,6 @@ <translation id="8068253693380742035">Klepnutím se přihlásíte</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Vytisknout jako obrázek</translation> -<translation id="8072988827236813198">Připnout karty</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Data aplikací mohou zahrnovat jakákoliv data, která uložila aplikace (v závislosti na nastavení vývojáře), včetně dat, jako jsou kontakty, zprávy a fotky.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Zálohovaná data se nezapočítávají do kvóty úložiště na Disku dítěte.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Tuto možnost můžete vypnout v Nastavení.<ph name="END_PARAGRAPH3" /></translation> @@ -4773,7 +4751,6 @@ <translation id="8368859634510605990">&Otevřít všechny záložky</translation> <translation id="8371695176452482769">Mluvte</translation> <translation id="8372369524088641025">Chybný klíč WEP</translation> -<translation id="8373553483208508744">Vypnout zvuk karet</translation> <translation id="8378714024927312812">Spravováno vaší organizací</translation> <translation id="8379878387931047019">Toto zařízení typ bezpečnostního klíče požadovaný tímto webem nepodporuje</translation> <translation id="8382913212082956454">Kopírovat &e-mailovou adresu</translation> @@ -4881,7 +4858,6 @@ <translation id="8546930481464505581">Přizpůsobit dotykovou plochu</translation> <translation id="8547013269961688403">Zapnout lupu celé obrazovky</translation> <translation id="85486688517848470">Podržením vyhledávacího tlačítka přepnete chování tlačítek v horním řádku</translation> -<translation id="855081842937141170">Připnout kartu</translation> <translation id="8551388862522347954">Licence</translation> <translation id="8553342806078037065">Spravovat ostatní uživatele</translation> <translation id="8554899698005018844">Žádný jazyk</translation> @@ -5195,7 +5171,6 @@ <translation id="9038430547971207796">Příště váš telefon zařízení <ph name="DEVICE_TYPE" /> odemkne. Funkci Smart Lock můžete vypnout v Nastavení.</translation> <translation id="9038649477754266430">Používat službu předpovídání k rychlejšímu načítání stránek</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Vypnout zvuk karet</translation> <translation id="9040661932550800571">Aktualizovat heslo pro web <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Správce přístup k místním souborům v tomto počítači zakázal</translation> <translation id="9042893549633094279">Ochrana soukromí a zabezpečení</translation> @@ -5293,7 +5268,6 @@ <translation id="920045321358709304">Hledat pomocí vyhledávače <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Možnosti zámku obrazovky</translation> <translation id="9203398526606335860">&Profilování povoleno</translation> -<translation id="9203478404496196495">Zapnout zvuk karty</translation> <translation id="9203904171912129171">Vyberte zařízení</translation> <translation id="9203962528777363226">Správce zařízení zakázal přidávat nové uživatele.</translation> <translation id="9213073329713032541">Instalace byla úspěšně spuštěna.</translation>
diff --git a/chrome/app/resources/generated_resources_da.xtb b/chrome/app/resources/generated_resources_da.xtb index 10fd682..331c783 100644 --- a/chrome/app/resources/generated_resources_da.xtb +++ b/chrome/app/resources/generated_resources_da.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Tryk på ESC for at springe over (kun uofficielle builds).</translation> <translation id="1093457606523402488">Synlige netværk:</translation> <translation id="1094607894174825014">Der blev anmodet om en læse- eller skrivehandling med en ugyldig forskydning på: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">Slå lyden til på websites</translation> <translation id="1097658378307015415">Før du logger ind, skal du logge ind som gæst for at aktivere netværket <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Oversæt altid <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Stop</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Brug internettet uden at gemme din browserhistorik ved hjælp af et inkognitovindue</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> fingeraftryk er registreret</translation> <translation id="1215411991991485844">Der er tilføjet en ny baggrunds-app</translation> -<translation id="1216654534877302979">Slå lyden fra på websites</translation> <translation id="1216659994753476700">Du kan desværre ikke få adgang til din profil. Filer og data, der er gemt på denne enhed, kan være gået tabt.<ph name="BR" /> <ph name="BR" /> Du er nødt til at oprette din profil igen.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Gemme data på din Google Drev-konto</translation> <translation id="1288037062697528143">Nattelys tændes automatisk ved solnedgang</translation> <translation id="1288300545283011870">Taleegenskaber</translation> -<translation id="1293177648337752319">Slå lyden til på et website</translation> <translation id="1293264513303784526">USB-C-enhed (venstre port)</translation> <translation id="1293556467332435079">Filer</translation> <translation id="1296497012903089238">Certifikattype</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Startsiden er siden Ny fane</translation> <translation id="1436671784520050284">Fortsæt konfiguration</translation> <translation id="1436784010935106834">Fjernet</translation> -<translation id="1438632560381091872">Slå fanernes lyd til</translation> <translation id="1442392616396121389">Omdirigeringspræfiks</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> er valgt</translation> <translation id="1444628761356461360">Denne indstilling administreres af enhedsejeren <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Der er tilsluttet et andet tastatur, siden du sidst indtastede din adgangskode. Det forsøger muligvis at stjæle dine indtastninger.</translation> <translation id="1567750922576943685">Bekræftelse af din identitet hjælper med at beskytte dine personlige oplysninger</translation> <translation id="1567993339577891801">JavaScript-konsol</translation> -<translation id="1568067597247500137">Slå lyden fra på et website</translation> <translation id="1568323446248056064">Åbn enhedens skærmindstillinger</translation> <translation id="1572266655485775982">Aktivér Wi-Fi</translation> <translation id="1572585716423026576">Angiv som baggrund</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">X9.62 ECDSA-signatur med SHA-1</translation> <translation id="1644574205037202324">Historik</translation> <translation id="1645516838734033527">For at beskytte din <ph name="DEVICE_TYPE" /> kræver Smart Lock en skærmlås på din telefon.</translation> -<translation id="1646102270785326155">Alle filer og lokale data, der er knyttet til denne bruger, slettes permanent, når denne bruger fjernes. $1 kan stadig logge ind senere.</translation> <translation id="1646982517418478057">Angiv en adgangskode til kryptering af dette certifikat</translation> <translation id="164814987133974965">En administreret bruger kan gå på internettet med din vejledning. Som administrator af en administreret bruger kan du <ph name="BEGIN_BOLD" />tillade eller forbyde<ph name="END_BOLD" /> visse websites, <ph name="BEGIN_BOLD" />gennemgå<ph name="END_BOLD" /> websites, som den administrerede bruger har besøgt, og <ph name="BEGIN_BOLD" />administrere<ph name="END_BOLD" /> andre indstillinger.</translation> <translation id="1648528859488547844">Brug Wi-Fi eller mobilnetværk til at fastslå placeringen</translation> @@ -496,7 +490,6 @@ <translation id="1729533290416704613">Den styrer også, hvilken side der vises, når du søger via omnifeltet.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Hvis du vil fjerne apps, skal du gå til Indstillinger > Google Play Butik > Administrer Android-præferencer > Apps eller Administration af apps. Tryk derefter på den app, du vil afinstallere (du skal muligvis stryge til højre eller venstre for at finde appen). Tryk derefter på Afinstaller eller Deaktiver.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Sender anmodning...</translation> -<translation id="1732215134274276513">Frigiv faner</translation> <translation id="1733383495376208985">Kryptér synkroniserede data med din egen <ph name="BEGIN_LINK" />adgangssætning til synkronisering<ph name="END_LINK" />. Dette omfatter ikke betalingsmetoder og adresser fra Google Pay.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> kan muligvis ikke holdes opdateret af sig selv</translation> <translation id="1736419249208073774">Mere</translation> @@ -548,7 +541,6 @@ <translation id="1807938677607439181">Alle filer</translation> <translation id="1809734401532861917">Føj mine bogmærker, min historik, mine adgangskoder og andre indstillinger til <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Ingen tilgængelig forhåndsvisning</translation> -<translation id="1812631533912615985">Frigiv faner</translation> <translation id="1813278315230285598">Tjenester</translation> <translation id="18139523105317219">EDI-partsnavn</translation> <translation id="1815083418640426271">Indsæt som almindelig tekst</translation> @@ -707,7 +699,6 @@ <translation id="2065405795449409761">Chrome kontrolleres af automatiseret testsoftware.</translation> <translation id="2070909990982335904">Navne, der begynder med punktum, må kun bruges af systemet. Vælg et andet navn.</translation> <translation id="2071393345806050157">Ingen lokal logfil.</translation> -<translation id="2074527029802029717">Frigør fane</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" /> % batteri</translation> <translation id="2075959085554270910">Giver dig mulighed for at aktivere/deaktivere tryk-hurtigt-for-at-klikke og Tryk og træk-funktionen</translation> <translation id="2076269580855484719">Skjul dette plugin</translation> @@ -1350,7 +1341,6 @@ <translation id="3045447014237878114">Dette website har downloadet flere filer automatisk</translation> <translation id="3046910703532196514">Webside, komplet</translation> <translation id="304747341537320566">Oplæsningsmaskiner</translation> -<translation id="304826556400666995">Slå fanernes lyd til</translation> <translation id="3053013834507634016">Brug af certifikatnøgle</translation> <translation id="3057861065630527966">Sikkerhedskopiér dine billeder og videoer</translation> <translation id="3060379269883947824">Aktivér Tekstoplæsning</translation> @@ -2333,7 +2323,6 @@ <translation id="4628762811416793313">Konfigurationen af Linux-containeren blev ikke fuldført. Prøv igen.</translation> <translation id="4628948037717959914">Billede</translation> <translation id="4631887759990505102">Kunstner</translation> -<translation id="4632483769545853758">Slå fanens lyd til</translation> <translation id="4633003931260532286">Udvidelsen skal bruge "<ph name="IMPORT_NAME" />" med minimumversionen "<ph name="IMPORT_VERSION" />", men kun versionen "<ph name="INSTALLED_VERSION" />" er installeret</translation> <translation id="4634771451598206121">Log ind igen...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> er ikke tilgængelig for gæstebrugere</translation> @@ -2397,7 +2386,6 @@ <translation id="4735803855089279419">Systemet kunne ikke fastslå enheds-id'erne for denne enhed.</translation> <translation id="4737715515457435632">Opret forbindelse til et netværk</translation> <translation id="473775607612524610">Opdater</translation> -<translation id="474217410105706308">Slå fanens lyd fra</translation> <translation id="4742746985488890273">Fastgør til hylde</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Se, hvordan du opdaterer apps<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Beskeder</translation> @@ -2622,7 +2610,6 @@ <translation id="5094721898978802975">Kommunikere med indbyggede apps</translation> <translation id="5097002363526479830">Der kunne ikke oprettes forbindelse til netværket "<ph name="NAME" />": <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Åbn alle bogmærker</translation> -<translation id="5105855035535475848">Fastgør faner</translation> <translation id="5108967062857032718">Indstillinger – Fjern Android-apps</translation> <translation id="5109044022078737958">Caroline</translation> <translation id="5111692334209731439">&Bogmærkeadministrator</translation> @@ -2687,7 +2674,6 @@ <translation id="520621735928254154">Fejl ved import af certifikat</translation> <translation id="5209320130288484488">Der blev ikke fundet nogen enheder</translation> <translation id="5209518306177824490">SHA-1-fingeraftryk</translation> -<translation id="5210365745912300556">Luk fanen</translation> <translation id="5213481667492808996">Din datatjeneste fra "<ph name="NAME" />" er klar til brug</translation> <translation id="5213891612754844763">Vis proxyindstillinger</translation> <translation id="521582610500777512">Billede blev kasseret</translation> @@ -2738,7 +2724,6 @@ <translation id="5270167208902136840">Vis <ph name="NUMBER_OF_MORE_APPS" /> apps mere</translation> <translation id="5275352920323889391">Hund</translation> <translation id="5275973617553375938">Gendannede filer fra Google Drev</translation> -<translation id="527605719918376753">Slå fanens lyd fra</translation> <translation id="527605982717517565">Tillad altid JavaScript på <ph name="HOST" /></translation> <translation id="5280426389926346830">Vil du oprette en genvej?</translation> <translation id="528208740344463258">Installer den påkrævede opdatering, før du kan downloade og bruge Android-apps. Du kan ikke bruge din <ph name="DEVICE_TYPE" />, mens den opdaterer. Din <ph name="DEVICE_TYPE" /> genstartes, når opdateringen er færdig.</translation> @@ -2861,7 +2846,6 @@ <translation id="5449551289610225147">Ugyldig adgangskode</translation> <translation id="5449588825071916739">Tilføj alle faner som bogmærker</translation> <translation id="5449716055534515760">Luk vin&due</translation> -<translation id="5453029940327926427">Luk faner</translation> <translation id="5454166040603940656">med <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Ugyldig</translation> <translation id="5457459357461771897">Læs og slet billeder, musik og andre medier på din computer</translation> @@ -3326,7 +3310,6 @@ <translation id="6122875415561139701">Skrivehandlingen er ikke tilladt på: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">Følgende udvidelser er afhængige af denne udvidelse:</translation> <translation id="6125479973208104919">Du skal desværre føje din konto til denne <ph name="DEVICE_TYPE" /> igen.</translation> -<translation id="612596694132302162">Slå lyden til på et website</translation> <translation id="6129691635767514872">De valgte data er blevet fjernet fra Chrome og synkroniserede enheder. Din Google-konto kan indeholde andre former for browserhistorik, f.eks. søgninger og aktivitet i andre Google-tjenester, på <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> <translation id="6129938384427316298">Kommentar til Netscape-certifikat</translation> <translation id="6129953537138746214">Mellemrum</translation> @@ -3530,7 +3513,6 @@ <translation id="6436164536244065364">Vis i Webshop</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – der afspilles lyd</translation> <translation id="6442187272350399447">Supernice</translation> -<translation id="6442697326824312960">Frigør fane</translation> <translation id="6444070574980481588">Angiv dato og klokkeslæt</translation> <translation id="6445450263907939268">Hvis du ikke var interesseret i disse ændringer, kan du gendanne dine tidligere indstillinger.</translation> <translation id="6447842834002726250">Cookies</translation> @@ -3733,7 +3715,6 @@ <translation id="6770664076092644100">Bekræft via NFC</translation> <translation id="6771503742377376720">Er en certificeringsautoritet</translation> <translation id="6777817260680419853">Omdirigeringen blev blokeret</translation> -<translation id="6778959797435875428">Slå lyden til på websites</translation> <translation id="677965093459947883">Meget lille</translation> <translation id="6780439250949340171">administrer andre indstillinger</translation> <translation id="6781284683813954823">Link til doodle</translation> @@ -4050,7 +4031,6 @@ <translation id="7257666756905341374">Læs de data, du kopierer og indsætter</translation> <translation id="7258697411818564379">Din pinkode er tilføjet</translation> <translation id="7262004276116528033">Denne logintjeneste hostes af <ph name="SAML_DOMAIN" />.</translation> -<translation id="7268365133021434339">Luk faner</translation> <translation id="7268659760406822741">Tilgængelige tjenester</translation> <translation id="7270858098575133036">Spørg mig, når et website vil anvende interne systemmeddelelser til at få adgang til MIDI-enheder</translation> <translation id="7272674038937250585">Der er ingen beskrivelse</translation> @@ -4240,7 +4220,6 @@ <translation id="7576032389798113292">6 x 4</translation> <translation id="7576690715254076113">Saml</translation> <translation id="7576976045740938453">Der opstod et problem med kontoen i demotilstand.</translation> -<translation id="7579149537961810247">Slå lyden fra på websites</translation> <translation id="7580671184200851182">Afspil den samme lyd via alle højttalere (monolyd)</translation> <translation id="7581462281756524039">Et oprydningsværktøj</translation> <translation id="7582582252461552277">Foretræk dette netværk</translation> @@ -4593,7 +4572,6 @@ <translation id="8068253693380742035">Tryk for at logge ind</translation> <translation id="8069615408251337349">Google Cloudprinter</translation> <translation id="8071432093239591881">Udskriv i billedformat</translation> -<translation id="8072988827236813198">Fastgør faner</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Appdata kan være alle former for data, som en app har gemt (baseret på udviklerens indstillinger), f.eks. kontakter, beskeder og billeder.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Sikkerhedskopierede data tæller ikke med i din kvote for Drev-lagerplads.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Du kan deaktivere denne tjeneste i Indstillinger.<ph name="END_PARAGRAPH3" /></translation> @@ -4779,7 +4757,6 @@ <translation id="8368859634510605990">&Åbn alle bogmærker</translation> <translation id="8371695176452482769">Indtal nu</translation> <translation id="8372369524088641025">Ugyldig WEP-nøgle</translation> -<translation id="8373553483208508744">Slå fanernes lyd fra</translation> <translation id="8378714024927312812">Administreret af din organisation</translation> <translation id="8379878387931047019">Denne enhed understøtter ikke den type sikkerhedsnøgle, der anmodes om på dette website</translation> <translation id="8382913212082956454">Kopier &e-mailadresse</translation> @@ -4887,7 +4864,6 @@ <translation id="8546930481464505581">Tilpas Touch Bar</translation> <translation id="8547013269961688403">Aktivér forstørrelse af fuld skærm</translation> <translation id="85486688517848470">Hold tasten Søg nede for at skifte funktion for den øverste række taster</translation> -<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> @@ -5202,7 +5178,6 @@ <translation id="9038430547971207796">Næste gang kan din telefon låse din <ph name="DEVICE_TYPE" /> op. Du kan slå Smart Lock fra i Indstillinger.</translation> <translation id="9038649477754266430">Brug en forudsigelsestjeneste til hurtigere sideindlæsning</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Slå fanernes lyd fra</translation> <translation id="9040661932550800571">Vil du opdatere adgangskoden til <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Din administrator har deaktiveret adgangen til lokale filer på din maskine</translation> <translation id="9042893549633094279">Sikkerhed og privatliv</translation> @@ -5300,7 +5275,6 @@ <translation id="920045321358709304">Søg via <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Valgmuligheder for skærmlås</translation> <translation id="9203398526606335860">&Profilering aktiveret</translation> -<translation id="9203478404496196495">Slå fanens lyd til</translation> <translation id="9203904171912129171">Vælg en enhed</translation> <translation id="9203962528777363226">Administratoren af denne enhed har deaktiveret tilføjelse af nye brugere</translation> <translation id="9213073329713032541">Installationen er startet.</translation>
diff --git a/chrome/app/resources/generated_resources_de.xtb b/chrome/app/resources/generated_resources_de.xtb index fea7593..84474d5 100644 --- a/chrome/app/resources/generated_resources_de.xtb +++ b/chrome/app/resources/generated_resources_de.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Drücken Sie die Esc-Taste, um die Aktualisierung zu überspringen (nur inoffizielle Builds).</translation> <translation id="1093457606523402488">Sichtbare Netzwerke:</translation> <translation id="1094607894174825014">Auf folgendem Gerät wurde ein Lese- oder Schreibvorgang mit ungültiger Abweichung angefordert: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">Stummschaltung für Websites aufheben</translation> <translation id="1097658378307015415">Melden Sie vor der Anmeldung als Gast an, um das Netzwerk <ph name="NETWORK_ID" /> zu aktivieren.</translation> <translation id="1103523840287552314"><ph name="LANGUAGE" /> immer übersetzen</translation> <translation id="1108600514891325577">&Anhalten</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">In einem Inkognitofenster können Sie surfen, ohne dass Ihr Browserverlauf gespeichert wird</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> Fingerabdrücke eingerichtet</translation> <translation id="1215411991991485844">Neue Hintergrund-App hinzugefügt</translation> -<translation id="1216654534877302979">Websites stummschalten</translation> <translation id="1216659994753476700">Wir können nicht auf Ihr Profil zugreifen. Die auf diesem Gerät gespeicherten Dateien und Daten sind möglicherweise verloren gegangen.<ph name="BR" /> <ph name="BR" /> Bitte richten Sie Ihr Profil wieder ein.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Daten in meinem Google Drive-Konto speichern</translation> <translation id="1288037062697528143">Das Nachtlicht wird bei Sonnenuntergang automatisch aktiviert</translation> <translation id="1288300545283011870">Sprecheigenschaften</translation> -<translation id="1293177648337752319">Stummschaltung für Website aufheben</translation> <translation id="1293264513303784526">USB-C-Gerät (Port links)</translation> <translation id="1293556467332435079">Dateien</translation> <translation id="1296497012903089238">Zertifikatstyp</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Die "Neuer Tab"-Seite ist die Startseite.</translation> <translation id="1436671784520050284">Einrichtung fortsetzen</translation> <translation id="1436784010935106834">Entfernt</translation> -<translation id="1438632560381091872">Stummschaltung der Tabs aufheben</translation> <translation id="1442392616396121389">Routing-Präfix</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> ausgewählt</translation> <translation id="1444628761356461360">Diese Einstellung wird vom Geräteinhaber, <ph name="OWNER_EMAIL" />, verwaltet.</translation> @@ -385,7 +381,6 @@ <translation id="1567387640189251553">Seit der letzten Eingabe Ihres Passwortes wurde eine andere Tastatur angeschlossen. Möglicherweise versucht jemand, darüber Ihre Tastatureingaben zu erfassen.</translation> <translation id="1567750922576943685">Wenn Ihre Identität überprüft werden kann, hilft dies, Ihre personenbezogenen Daten zu schützen</translation> <translation id="1567993339577891801">JavaScript-Konsole</translation> -<translation id="1568067597247500137">Website stummschalten</translation> <translation id="1568323446248056064">Einstellungen für Anzeigegerät öffnen</translation> <translation id="1572266655485775982">WLAN-Aktivierung</translation> <translation id="1572585716423026576">Als Hintergrund festlegen</translation> @@ -437,7 +432,6 @@ <translation id="1643072738649235303">X9.62-ECDSA-Signatur mit SHA-1</translation> <translation id="1644574205037202324">Verlauf</translation> <translation id="1645516838734033527">Damit Smart Lock Ihr <ph name="DEVICE_TYPE" /> schützen kann, muss auf Ihrem Smartphone die Displaysperre eingerichtet sein.</translation> -<translation id="1646102270785326155">Durch das Entfernen des Nutzers werden alle mit ihm verknüpften Dateien und lokalen Daten endgültig gelöscht. $1 kann sich später immer noch anmelden.</translation> <translation id="1646982517418478057">Bitte geben Sie ein Passwort zur Verschlüsselung dieses Zertifikats ein</translation> <translation id="164814987133974965">Sie können die Websuche betreuter Nutzer beeinflussen. Als Manager eines betreuten Nutzers können Sie bestimmte Websites <ph name="BEGIN_BOLD" />freigeben oder sperren<ph name="END_BOLD" />, @@ -496,7 +490,6 @@ <translation id="1729533290416704613">Die Erweiterung legt auch fest, welche Seite bei der Suche über die Omnibox angezeigt wird.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Wenn Sie eine App entfernen möchten, gehen Sie zu "Einstellungen" > "Google Play Store" > "Android-Einstellungen verwalten" > "Apps" oder rufen Sie den Anwendungsmanager auf. Tippen Sie dann auf die App, die Sie deinstallieren möchten, und wählen Sie "Deinstallieren" oder "Deaktivieren" aus. Möglicherweise müssen Sie nach rechts oder links wischen, um die App zu finden.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Anfrage wird gesendet...</translation> -<translation id="1732215134274276513">Tabs loslösen</translation> <translation id="1733383495376208985">Alle synchronisierten Daten mit eigener <ph name="BEGIN_LINK" />Synchronisierungspassphrase<ph name="END_LINK" /> verschlüsseln (außer Zahlungsmethoden oder Adressen von Google Pay)</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> kann sich möglicherweise nicht selbst aktualisieren</translation> <translation id="1736419249208073774">Entdecken</translation> @@ -548,7 +541,6 @@ <translation id="1807938677607439181">Alle Dateien</translation> <translation id="1809734401532861917">Meine Lesezeichen, den Verlauf, Passwörter und andere Einstellungen zu <ph name="USER_EMAIL_ADDRESS" /> hinzufügen</translation> <translation id="1810764548349082891">Keine Vorschau verfügbar</translation> -<translation id="1812631533912615985">Tabs loslösen</translation> <translation id="1813278315230285598">Dienste</translation> <translation id="18139523105317219">Name der EDI-Partei</translation> <translation id="1815083418640426271">Als unformatierten Text einfügen</translation> @@ -707,7 +699,6 @@ <translation id="2065405795449409761">Chrome wird von automatisierter Testsoftware gesteuert.</translation> <translation id="2070909990982335904">Namen, die mit einem Punkt beginnen, sind für das System reserviert. Wählen Sie einen anderen Namen aus.</translation> <translation id="2071393345806050157">Keine lokale Protokolldatei vorhanden</translation> -<translation id="2074527029802029717">Tab loslösen</translation> <translation id="2075474481720804517">Akkustand <ph name="BATTERY_PERCENTAGE" /> %</translation> <translation id="2075959085554270910">Ermöglicht das Aktivieren/Deaktivieren des Touchpad-Klicks und der Funktion zum Antippen und Ziehen</translation> <translation id="2076269580855484719">Dieses Plug-in ausblenden</translation> @@ -1347,7 +1338,6 @@ <translation id="3045447014237878114">Diese Website hat automatisch mehrere Dateien heruntergeladen</translation> <translation id="3046910703532196514">Webseite, vollständig</translation> <translation id="304747341537320566">Sprach-Engines</translation> -<translation id="304826556400666995">Stummschaltung der Tabs aufheben</translation> <translation id="3053013834507634016">Zertifikatschlüsselverwendung</translation> <translation id="3057861065630527966">Fotos und Videos sichern</translation> <translation id="3060379269883947824">Vorlesen aktivieren</translation> @@ -2330,7 +2320,6 @@ <translation id="4628762811416793313">Die Einrichtung des Linux-Containers wurde nicht abgeschlossen. Bitte versuchen Sie es noch einmal.</translation> <translation id="4628948037717959914">Foto</translation> <translation id="4631887759990505102">Musiker</translation> -<translation id="4632483769545853758">Stummschaltung des Tabs aufheben</translation> <translation id="4633003931260532286">Die Erweiterung erfordert "<ph name="IMPORT_NAME" />" mit der Mindestversion "<ph name="IMPORT_VERSION" />", es ist jedoch nur Version "<ph name="INSTALLED_VERSION" />" installiert</translation> <translation id="4634771451598206121">Erneut anmelden...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> ist für Gastnutzer nicht verfügbar.</translation> @@ -2394,7 +2383,6 @@ <translation id="4735803855089279419">Das System konnte die Gerätekennungen für dieses Gerät nicht ermitteln.</translation> <translation id="4737715515457435632">Bitte stellen Sie eine Verbindung zu einem Netzwerk her.</translation> <translation id="473775607612524610">Aktualisieren</translation> -<translation id="474217410105706308">Tab stummschalten</translation> <translation id="4742746985488890273">An Ablage anpinnen</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Hier finden Sie Informationen zum Aktualisieren von Anwendungen<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Nachrichten</translation> @@ -2619,7 +2607,6 @@ <translation id="5094721898978802975">Mit zusammenarbeitenden systemeigenen Anwendungen kommunizieren</translation> <translation id="5097002363526479830">Fehler beim Herstellen einer Verbindung mit dem Netzwerk "<ph name="NAME" />": <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Alle Lesezeichen öffnen</translation> -<translation id="5105855035535475848">Tabs anpinnen</translation> <translation id="5108967062857032718">Einstellungen – Android-Apps entfernen</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">&Lesezeichen-Manager</translation> @@ -2684,7 +2671,6 @@ <translation id="520621735928254154">Fehler beim Importieren des Zertifikats</translation> <translation id="5209320130288484488">Keine Geräte gefunden</translation> <translation id="5209518306177824490">SHA-1-Fingerabdruck</translation> -<translation id="5210365745912300556">Schließen</translation> <translation id="5213481667492808996">Der "<ph name="NAME" />"-Datendienst kann nun verwendet werden</translation> <translation id="5213891612754844763">Proxyeinstellungen anzeigen</translation> <translation id="521582610500777512">Das Foto wurde verworfen.</translation> @@ -2735,7 +2721,6 @@ <translation id="5270167208902136840"><ph name="NUMBER_OF_MORE_APPS" /> weitere Apps anzeigen</translation> <translation id="5275352920323889391">Hund</translation> <translation id="5275973617553375938">Wiederhergestellte Dateien von Google Drive</translation> -<translation id="527605719918376753">Stummschalten</translation> <translation id="527605982717517565">JavaScript auf <ph name="HOST" /> immer zulassen</translation> <translation id="5280426389926346830">Verknüpfung erstellen?</translation> <translation id="528208740344463258">Wenn Sie Android-Apps herunterladen und verwenden möchten, müssen Sie zuerst dieses erforderliche Update installieren. Sie können Ihr <ph name="DEVICE_TYPE" /> während des Updates nicht nutzen. Nach Abschluss der Installation wird Ihr <ph name="DEVICE_TYPE" /> neu gestartet.</translation> @@ -2858,7 +2843,6 @@ <translation id="5449551289610225147">Ungültiges Passwort</translation> <translation id="5449588825071916739">Alle Tabs als Lesezeichen speichern</translation> <translation id="5449716055534515760">Fen&ster schließen</translation> -<translation id="5453029940327926427">Tabs schließen</translation> <translation id="5454166040603940656">mit <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Ungültig</translation> <translation id="5457459357461771897">Fotos, Musik und andere Medien auf Ihrem Computer lesen und löschen</translation> @@ -3323,7 +3307,6 @@ <translation id="6122875415561139701">Der Schreibvorgang ist auf folgendem Gerät nicht erlaubt: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">Die folgenden Erweiterungen hängen von dieser Erweiterung ab:</translation> <translation id="6125479973208104919">Sie müssen Ihr Konto dem <ph name="DEVICE_TYPE" /> erneut hinzufügen.</translation> -<translation id="612596694132302162">Stummschaltung für Website aufheben</translation> <translation id="6129691635767514872">Die ausgewählten Daten wurden aus Chrome und von synchronisierten Geräten entfernt. Ihr Google-Konto weist möglicherweise andere Formen von Browserverläufen wie Suchanfragen und Aktivitäten von anderen Google-Diensten unter <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> auf.</translation> <translation id="6129938384427316298">Kommentar zu Netscape-Zertifikaten</translation> <translation id="6129953537138746214">Leerzeichen</translation> @@ -3526,7 +3509,6 @@ <translation id="6436164536244065364">Im Web Store ansehen</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – Audiowiedergabe</translation> <translation id="6442187272350399447">Smiley</translation> -<translation id="6442697326824312960">Tab loslösen</translation> <translation id="6444070574980481588">Datum und Uhrzeit festlegen</translation> <translation id="6445450263907939268">Wenn Sie diese Änderungen nicht beabsichtigt hatten, können Sie Ihre vorherigen Einstellungen wiederherstellen.</translation> <translation id="6447842834002726250">Cookies</translation> @@ -3729,7 +3711,6 @@ <translation id="6770664076092644100">Über NFC bestätigen</translation> <translation id="6771503742377376720">Ist eine Zertifizierungsstelle</translation> <translation id="6777817260680419853">Weiterleitung blockiert</translation> -<translation id="6778959797435875428">Stummschaltung für Websites aufheben</translation> <translation id="677965093459947883">Sehr klein</translation> <translation id="6780439250949340171">andere Einstellungen verwalten</translation> <translation id="6781284683813954823">Doodle-Link</translation> @@ -4046,7 +4027,6 @@ <translation id="7257666756905341374">Daten lesen, die Sie kopieren und einfügen</translation> <translation id="7258697411818564379">PIN wurde hinzugefügt</translation> <translation id="7262004276116528033">Dieser Anmeldedienst wird von <ph name="SAML_DOMAIN" /> gehostet.</translation> -<translation id="7268365133021434339">Tabs schließen</translation> <translation id="7268659760406822741">Verfügbare Dienste</translation> <translation id="7270858098575133036">Nachfragen, wenn eine Website versucht, mit systemexklusiven Meldungen auf MIDI-Geräte zuzugreifen</translation> <translation id="7272674038937250585">Keine Beschreibung vorhanden</translation> @@ -4236,7 +4216,6 @@ <translation id="7576032389798113292">6 x 4</translation> <translation id="7576690715254076113">Zuordnen</translation> <translation id="7576976045740938453">Ein Problem mit dem Konto für den Demomodus ist aufgetreten.</translation> -<translation id="7579149537961810247">Websites stummschalten</translation> <translation id="7580671184200851182">Dieselben Audioinhalte über alle Lautsprecher wiedergeben (Mono-Audio)</translation> <translation id="7581462281756524039">Ein Bereinigungstool</translation> <translation id="7582582252461552277">Dieses Netzwerk bevorzugen</translation> @@ -4590,7 +4569,6 @@ <translation id="8068253693380742035">Zum Anmelden tippen</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Als Bild drucken</translation> -<translation id="8072988827236813198">Tabs anpinnen</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />App-Daten können alle Daten sein, die von einer App basierend auf den Entwicklereinstellungen gespeichert wurden, einschließlich Daten wie Kontakte, Nachrichten und Fotos.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Die Sicherungsdaten werden nicht auf das Google Drive-Speicherkontingent Ihres Kindes angerechnet.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Sie können diesen Dienst in den Einstellungen deaktivieren.<ph name="END_PARAGRAPH3" /></translation> @@ -4776,7 +4754,6 @@ <translation id="8368859634510605990">&Alle Lesezeichen öffnen</translation> <translation id="8371695176452482769">Jetzt sprechen</translation> <translation id="8372369524088641025">Ungültiger WEP-Schlüssel</translation> -<translation id="8373553483208508744">Tabs stummschalten</translation> <translation id="8378714024927312812">Von Ihrer Organisation verwaltet</translation> <translation id="8379878387931047019">Das Gerät ist nicht mit dem Sicherheitsschlüssel kompatibel, der von dieser Website angefordert wird</translation> <translation id="8382913212082956454">E-Mail-Adr&esse kopieren</translation> @@ -4884,7 +4861,6 @@ <translation id="8546930481464505581">Touch Bar anpassen</translation> <translation id="8547013269961688403">Vollbildlupe aktivieren</translation> <translation id="85486688517848470">Halten Sie die Suchtaste gedrückt, um die Funktion der Tasten in der obersten Reihe zu ändern</translation> -<translation id="855081842937141170">Anpinnen</translation> <translation id="8551388862522347954">Lizenzen</translation> <translation id="8553342806078037065">Andere Nutzer verwalten</translation> <translation id="8554899698005018844">Keine Sprache</translation> @@ -5199,7 +5175,6 @@ <translation id="9038649477754266430">Vorhersagefunktion zum schnelleren Laden von Seiten verwenden </translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Tabs stummschalten</translation> <translation id="9040661932550800571">Passwort für <ph name="ORIGIN" /> aktualisieren?</translation> <translation id="9041692268811217999">Der Zugriff auf lokale Dateien auf Ihrem Gerät wurde von Ihrem Administrator deaktiviert</translation> <translation id="9042893549633094279">Datenschutz und Sicherheit</translation> @@ -5297,7 +5272,6 @@ <translation id="920045321358709304"><ph name="SEARCH_ENGINE" />-Suche</translation> <translation id="9201220332032049474">Optionen für die Displaysperre</translation> <translation id="9203398526606335860">&Profilerstellung aktiviert</translation> -<translation id="9203478404496196495">Stummschaltung des Tabs aufheben</translation> <translation id="9203904171912129171">Gerät auswählen</translation> <translation id="9203962528777363226">Der Administrator dieses Geräts hat die Funktion zum Hinzufügen neuer Nutzer deaktiviert.</translation> <translation id="9213073329713032541">Die Installation wurde gestartet.</translation>
diff --git a/chrome/app/resources/generated_resources_el.xtb b/chrome/app/resources/generated_resources_el.xtb index 8556c388..774c4c4 100644 --- a/chrome/app/resources/generated_resources_el.xtb +++ b/chrome/app/resources/generated_resources_el.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Πατήστε ESCAPE για παράλειψη (Μόνο για ανεπίσημες εκδόσεις).</translation> <translation id="1093457606523402488">Ορατά δίκτυα:</translation> <translation id="1094607894174825014">Η λειτουργία ανάγνωσης ή γραφής ζητήθηκε με μη έγκυρη μετατόπιση στη συσκευή: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">Κατάργηση σίγασης ιστοτόπων</translation> <translation id="1097658378307015415">Προτού συνδεθείτε, πραγματοποιήστε είσοδο ως επισκέπτης για να ενεργοποιηθεί το δίκτυο <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Να μεταφράζονται πάντα τα <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Διακοπή</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Χρησιμοποιήστε τον ιστό χωρίς να αποθηκεύσετε το ιστορικό περιήγησής σας με ένα παράθυρο για ανώνυμη περιήγηση</translation> <translation id="1213037489357051291">Ρυθμίστηκαν <ph name="NUM_FINGERPRINTS" /> δακτυλικά αποτυπώματα</translation> <translation id="1215411991991485844">Προστέθηκε νέα εφαρμογή παρασκηνίου</translation> -<translation id="1216654534877302979">Σίγαση ιστοτόπων</translation> <translation id="1216659994753476700">Δυστυχώς, δεν μπορούμε να ανοίξουμε το προφίλ σας. Ενδέχεται να έχουν χαθεί αρχεία και δεδομένα που είχαν αποθηκευτεί σε αυτήν τη συσκευή.<ph name="BR" /> <ph name="BR" /> Θα πρέπει να ρυθμίσετε ξανά το προφίλ σας.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Αποθήκευση δεδομένων στο λογαριασμό σας στο Google Drive</translation> <translation id="1288037062697528143">Ο Νυχτερινός φωτισμός θα ενεργοποιηθεί αυτόματα.</translation> <translation id="1288300545283011870">Ιδιότητες ομιλίας</translation> -<translation id="1293177648337752319">Κατάργηση σίγασης Ιστοτόπου</translation> <translation id="1293264513303784526">Συσκευή USB-C (αριστερή θύρα)</translation> <translation id="1293556467332435079">Αρχεία</translation> <translation id="1296497012903089238">Τύπος πιστοποιητικού</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Η αρχική σελίδα είναι η σελίδα "Νέα καρτέλα"</translation> <translation id="1436671784520050284">Συνέχιση ρύθμισης</translation> <translation id="1436784010935106834">Καταργήθηκαν</translation> -<translation id="1438632560381091872">Κατάργηση σίγασης καρτελών</translation> <translation id="1442392616396121389">Πρόθημα δρομολόγησης</translation> <translation id="144283815522798837">Επιλέχθηκαν <ph name="NUMBER_OF_ITEMS_SELECTED" /> στοιχεία</translation> <translation id="1444628761356461360">Η διαχείριση αυτής της ρύθμισης πραγματοποιείται από τον ιδιοκτήτη της συσκευής, <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Συνδέθηκε διαφορετικό πληκτρολόγιο από την τελευταία φορά που εισαγάγατε τον κωδικό πρόσβασής σας. Μπορεί να επιχειρεί να υποκλέψει τα πατήματα πλήκτρων σας.</translation> <translation id="1567750922576943685">Η επαλήθευση της ταυτότητάς σας συμβάλλει στην προστασία των προσωπικών στοιχείων σας</translation> <translation id="1567993339577891801">Κονσόλα JavaScript</translation> -<translation id="1568067597247500137">Σίγαση ιστοτόπου</translation> <translation id="1568323446248056064">Άνοιγμα των ρυθμίσεων οθόνης της συσκευής</translation> <translation id="1572266655485775982">Ενεργοποίηση Wi-Fi</translation> <translation id="1572585716423026576">Ορισμός ως ταπετσαρία</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">Υπογραφή X9.62 ECDSA με SHA-1</translation> <translation id="1644574205037202324">Ιστορικό</translation> <translation id="1645516838734033527">Το Smart Lock, για να διατηρήσει το <ph name="DEVICE_TYPE" /> ασφαλές, απαιτεί κλείδωμα οθόνης στο τηλέφωνό σας.</translation> -<translation id="1646102270785326155">Όλα τα αρχεία και τα τοπικά δεδομένα που σχετίζονται με τον χρήστη θα διαγραφούν οριστικά μόλις ο χρήστης καταργηθεί. Ο χρήστης $1 θα μπορεί να συνδεθεί αργότερα.</translation> <translation id="1646982517418478057">Εισαγάγετε έναν κωδικό πρόσβασης για την κρυπτογράφηση αυτού του πιστοποιητικού</translation> <translation id="164814987133974965">Ένας εποπτευόμενος χρήστης μπορεί να εξερευνήσει τον ιστό με την καθοδήγησή σας. Ως διαχειριστής ενός εποπτευόμενου χρήστη, μπορείτε να <ph name="BEGIN_BOLD" />επιτρέπετε ή να απαγορεύετε την πρόσβαση<ph name="END_BOLD" /> σε συγκεκριμένους ιστότοπους, να @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Επίσης, ελέγχει τη σελίδα που εμφανίζεται όταν κάνετε αναζήτηση από το κύριο πλαίσιο.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Για να καταργήσετε εφαρμογές, μεταβείτε στις Ρυθμίσεις > Google Play Store > Διαχείριση προτιμήσεων Android > Εφαρμογές ή Διαχείριση εφαρμογών. Έπειτα, πατήστε την εφαρμογή που θέλετε να απεγκαταστήσετε (μπορεί να χρειαστεί να σύρετε προς τα δεξιά ή προς τα αριστερά για να βρείτε την εφαρμογή). Στη συνέχεια, πατήστε Απεγκατάσταση ή Απενεργοποίηση.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Αποστολή αίτησης...</translation> -<translation id="1732215134274276513">Ξεκαρφίτσωμα καρτελών</translation> <translation id="1733383495376208985">Κρυπτογραφήστε δεδομένα συγχρονισμού με τη δική σας <ph name="BEGIN_LINK" />φράση πρόσβασης συγχρονισμού<ph name="END_LINK" />. Αυτά τα δεδομένα δεν περιλαμβάνουν τρόπους πληρωμής και διευθύνσεις από το Google Pay.</translation> <translation id="1734824808160898225">Μπορεί να μην είναι δυνατή η αυτόματη ενημέρωση του <ph name="PRODUCT_NAME" /></translation> <translation id="1736419249208073774">Εξερεύνηση</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Όλα τα αρχεία</translation> <translation id="1809734401532861917">Προσθήκη των σελιδοδεικτών, του ιστορικού, των κωδικών πρόσβασης και άλλων ρυθμίσεών μου στον λογαριασμό <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Δεν υπάρχει διαθέσιμη προεπισκόπηση</translation> -<translation id="1812631533912615985">Ξεκαρφίτσωμα καρτελών</translation> <translation id="1813278315230285598">Υπηρεσίες</translation> <translation id="18139523105317219">Όνομα μέρους EDI</translation> <translation id="1815083418640426271">Επικόλληση ως απλό κείμενο</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Το Chrome ελέγχεται από λογισμικό αυτοματοποιημένου ελέγχου.</translation> <translation id="2070909990982335904">Τα ονόματα που αρχίζουν με τελεία προορίζονται για το σύστημα. Επιλέξτε ένα άλλο όνομα.</translation> <translation id="2071393345806050157">Δεν υπάρχει τοπικό αρχείο καταγραφής.</translation> -<translation id="2074527029802029717">Ξεκαρφίτσωμα καρτέλας</translation> <translation id="2075474481720804517">Μπαταρία <ph name="BATTERY_PERCENTAGE" />%</translation> <translation id="2075959085554270910">Σας επιτρέπει να ενεργοποιήσετε/απενεργοποιήσετε τη λειτουργία "άγγιγμα για κλικ" και τη μεταφορά με πάτημα</translation> <translation id="2076269580855484719">Απόκρυψη αυτής της προσθήκης</translation> @@ -1352,7 +1343,6 @@ <translation id="3045447014237878114">Αυτός ο ιστότοπος κατέβασε αυτόματα πολλά αρχεία</translation> <translation id="3046910703532196514">Ιστοσελίδα, πλήρης</translation> <translation id="304747341537320566">Μηχανές ομιλίας</translation> -<translation id="304826556400666995">Κατάργηση σίγασης καρτελών</translation> <translation id="3053013834507634016">Χρήση κλειδιού πιστοποιητικού</translation> <translation id="3057861065630527966">Δημιουργία αντιγράφων ασφαλείας για τις φωτογραφίες και τα βίντεό σας</translation> <translation id="3060379269883947824">Ενεργοποίηση λειτουργίας "Επιλέξτε για εκφώνηση"</translation> @@ -2335,7 +2325,6 @@ <translation id="4628762811416793313">Η ρύθμιση του κοντέινερ Linux δεν ολοκληρώθηκε. Δοκιμάστε ξανά.</translation> <translation id="4628948037717959914">Φωτογραφία</translation> <translation id="4631887759990505102">Καλλιτέχνης</translation> -<translation id="4632483769545853758">Κατάργηση σίγασης καρτέλας</translation> <translation id="4633003931260532286">Η επέκταση απαιτεί "<ph name="IMPORT_NAME" />" με ελάχιστη έκδοση "<ph name="IMPORT_VERSION" />", αλλά είναι εγκατεστημένη μόνο η έκδοση "<ph name="INSTALLED_VERSION" />"</translation> <translation id="4634771451598206121">Συνδεθείτε ξανά...</translation> <translation id="4635398712689569051">Η σελίδα <ph name="PAGE_NAME" /> δεν είναι διαθέσιμη σε επισκέπτες.</translation> @@ -2399,7 +2388,6 @@ <translation id="4735803855089279419">Το σύστημα δεν κατάφερε να προσδιορίσει αναγνωριστικά συσκευής για αυτήν τη συσκευή.</translation> <translation id="4737715515457435632">Συνδεθείτε σε ένα δίκτυο</translation> <translation id="473775607612524610">Ενημέρωση</translation> -<translation id="474217410105706308">Σίγαση καρτέλας</translation> <translation id="4742746985488890273">Καρφίτσωμα στο ράφι</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Μάθετε πώς μπορείτε να ενημερώνετε τις εφαρμογές<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Μηνύματα</translation> @@ -2624,7 +2612,6 @@ <translation id="5094721898978802975">Επικοινωνία με συνεργαζόμενες εγγενείς εφαρμογές</translation> <translation id="5097002363526479830">Δεν ήταν δυνατή η σύνδεση στο δίκτυο '<ph name="NAME" />': <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Άνοιγμα όλων των σελιδοδεικτών</translation> -<translation id="5105855035535475848">Καρφίτσωμα καρτελών</translation> <translation id="5108967062857032718">Ρυθμίσεις - Κατάργηση εφαρμογών Android</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">&Διαχείριση Σελιδοδεικτών</translation> @@ -2689,7 +2676,6 @@ <translation id="520621735928254154">Σφάλμα εισαγωγής πιστοποιητικού</translation> <translation id="5209320130288484488">Δεν βρέθηκαν συσκευές</translation> <translation id="5209518306177824490">Αποτύπωμα SHA-1</translation> -<translation id="5210365745912300556">Κλείσιμο καρτέλας</translation> <translation id="5213481667492808996">Η υπηρεσία δεδομένων "<ph name="NAME" />" είναι έτοιμη για χρήση</translation> <translation id="5213891612754844763">Προβολή ρυθμίσεων διακομιστή μεσολάβησης</translation> <translation id="521582610500777512">Η φωτογραφία απορρίφτηκε</translation> @@ -2740,7 +2726,6 @@ <translation id="5270167208902136840">Εμφάνιση <ph name="NUMBER_OF_MORE_APPS" /> επιπλέον εφαρμογών</translation> <translation id="5275352920323889391">Σκύλος</translation> <translation id="5275973617553375938">Ανακτημένα αρχεία από το Google Drive</translation> -<translation id="527605719918376753">Σίγαση καρτέλας</translation> <translation id="527605982717517565">Να επιτρέπεται πάντα το JavaScript στο <ph name="HOST" /></translation> <translation id="5280426389926346830">Δημιουργία συντόμευσης;</translation> <translation id="528208740344463258">Για να κατεβάσετε και να χρησιμοποιήσετε εφαρμογές Android, θα πρέπει πρώτα να εγκαταστήσετε αυτήν την υποχρεωτική ενημέρωση. Δεν είναι δυνατή η χρήση της συσκευής <ph name="DEVICE_TYPE" /> κατά τη διάρκεια της ενημέρωσης. Μόλις ολοκληρωθεί η εγκατάσταση, θα γίνει επανεκκίνηση της συσκευής <ph name="DEVICE_TYPE" />.</translation> @@ -2863,7 +2848,6 @@ <translation id="5449551289610225147">Μη έγκυρος κωδικός πρόσβασης</translation> <translation id="5449588825071916739">Δημιουργία σελιδοδείκτη για όλες τις καρτέλες</translation> <translation id="5449716055534515760">Κλείσιμο παραθύρου</translation> -<translation id="5453029940327926427">Κλείσιμο καρτελών</translation> <translation id="5454166040603940656">με <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Μη έγκυρο</translation> <translation id="5457459357461771897">Ανάγνωση και διαγραφή φωτογραφιών, μουσικής και άλλων μέσων από τον υπολογιστή σας</translation> @@ -3329,7 +3313,6 @@ <translation id="6122875415561139701">Η λειτουργία εγγραφής δεν επιτρέπεται στη συσκευή: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">Οι ακόλουθες επεκτάσεις εξαρτώνται από αυτήν την επέκταση:</translation> <translation id="6125479973208104919">Δυστυχώς, θα πρέπει να προσθέσετε ξανά τον λογαριασμό σας σε αυτήν τη συσκευή <ph name="DEVICE_TYPE" />.</translation> -<translation id="612596694132302162">Κατάργηση σίγασης ιστοτόπου</translation> <translation id="6129691635767514872">Τα επιλεγμένα δεδομένα καταργήθηκαν από το Chrome και από τις συγχρονισμένες συσκευές. Ο Λογαριασμός σας Google μπορεί να διαθέτει άλλες μορφές ιστορικού περιήγησης, όπως αναζητήσεις και δραστηριότητα από άλλες υπηρεσίες Google στη διεύθυνση <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Σχόλιο πιστοποιητικού Netscape</translation> <translation id="6129953537138746214">Κενό</translation> @@ -3532,7 +3515,6 @@ <translation id="6436164536244065364">Προβολή στο Web Store</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - Αναπαραγωγή ήχου</translation> <translation id="6442187272350399447">Φανταστικό</translation> -<translation id="6442697326824312960">Ξεκαρφίτσωμα καρτέλας</translation> <translation id="6444070574980481588">Ορισμός ημερομηνίας και ώρας</translation> <translation id="6445450263907939268">Αν δεν επιθυμείτε να γίνουν αυτές οι αλλαγές, μπορείτε να επαναφέρετε τις προηγούμενες ρυθμίσεις σας.</translation> <translation id="6447842834002726250">Cookies</translation> @@ -3735,7 +3717,6 @@ <translation id="6770664076092644100">Επαλήθευση μέσω NFC</translation> <translation id="6771503742377376720">Είναι Αρχή πιστοποίησης</translation> <translation id="6777817260680419853">Η ανακατεύθυνση αποκλείστηκε</translation> -<translation id="6778959797435875428">Κατάργηση σίγασης ιστοτόπων</translation> <translation id="677965093459947883">Πολύ μικρό</translation> <translation id="6780439250949340171">διαχείριση άλλων ρυθμίσεων</translation> <translation id="6781284683813954823">Σύνδεσμος doodle</translation> @@ -4052,7 +4033,6 @@ <translation id="7257666756905341374">Ανάγνωση δεδομένων που αντιγράφετε και επικολλάτε</translation> <translation id="7258697411818564379">Το PIN προστίθεται</translation> <translation id="7262004276116528033">Η υπηρεσία σύνδεσης φιλοξενείται από τον τομέα <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Κλείσιμο καρτελών</translation> <translation id="7268659760406822741">Διαθέσιμες υπηρεσίες</translation> <translation id="7270858098575133036">Να γίνεται ερώτηση όταν ένας ιστότοπος θέλει να χρησιμοποιήσει αποκλειστικά μηνύματα συστήματος για την πρόσβαση σε συσκευές MIDI</translation> <translation id="7272674038937250585">Χωρίς περιγραφή</translation> @@ -4242,7 +4222,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">Συρραφή</translation> <translation id="7576976045740938453">Παρουσιάστηκε πρόβλημα με τον λογαριασμό επίδειξης.</translation> -<translation id="7579149537961810247">Σίγαση Ιστοτόπων</translation> <translation id="7580671184200851182">Αναπαραγωγή του ίδιου ήχου μέσω όλων των ηχείων (μονοφωνικός ήχος)</translation> <translation id="7581462281756524039">Ένα εργαλείο καθαρισμού</translation> <translation id="7582582252461552277">Προτίμηση αυτού του δικτύου</translation> @@ -4596,7 +4575,6 @@ <translation id="8068253693380742035">Αγγίξτε για να συνδεθείτε</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Εκτύπωση ως εικόνα</translation> -<translation id="8072988827236813198">Καρφίτσωμα καρτελων </translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Τα δεδομένα εφαρμογής μπορεί να είναι οποιουδήποτε είδους δεδομένα έχουν αποθηκευτεί από μια εφαρμογή (βάσει των ρυθμίσεων προγραμματιστή σας), συμπεριλαμβανομένων δεδομένων όπως επαφών, μηνυμάτων και φωτογραφιών.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Τα δεδομένα αντιγράφων ασφαλείας δεν υπολογίζονται στο όριο του αποθηκευτικού χώρου του παιδιού σας στο Drive.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Μπορείτε να απενεργοποιήσετε αυτήν την υπηρεσία από τις Ρυθμίσεις.<ph name="END_PARAGRAPH3" /></translation> @@ -4782,7 +4760,6 @@ <translation id="8368859634510605990">Ά&νοιγμα όλων των σελιδοδεικτών</translation> <translation id="8371695176452482769">Μιλήστε τώρα</translation> <translation id="8372369524088641025">Εσφαλμένο κλειδί WEP</translation> -<translation id="8373553483208508744">Σίγαση καρτελών</translation> <translation id="8378714024927312812">Διαχειριζόμενο από τον οργανισμό σας</translation> <translation id="8379878387931047019">Αυτή η συσκευή δεν υποστηρίζει τον τύπο του κλειδιού ασφαλείας που ζητήθηκε από αυτόν τον ιστότοπο</translation> <translation id="8382913212082956454">Αντιγραφή διεύθυνσης &ηλεκτρονικού ταχυδρομείου</translation> @@ -4890,7 +4867,6 @@ <translation id="8546930481464505581">Προσαρμογή της γραμμής αφής</translation> <translation id="8547013269961688403">Ενεργοποίηση μεγεθυντικού φακού πλήρους οθόνης</translation> <translation id="85486688517848470">Πατήστε παρατεταμένα το πλήκτρο αναζήτησης για να αλλάξετε τη συμπεριφορά των πλήκτρων της επάνω σειράς</translation> -<translation id="855081842937141170">Καρφίτσωμα καρτέλας</translation> <translation id="8551388862522347954">Άδειες</translation> <translation id="8553342806078037065">Διαχείριση άλλων ατόμων</translation> <translation id="8554899698005018844">Καμία γλώσσα</translation> @@ -5202,7 +5178,6 @@ <translation id="9038430547971207796">Την επόμενη φορά, το τηλέφωνό σας θα ξεκλειδώσει το <ph name="DEVICE_TYPE" />. Απενεργοποιήστε το Smart Lock στις Ρυθμίσεις.</translation> <translation id="9038649477754266430">Χρήση μιας υπηρεσίας πρόβλεψης για ταχύτερη φόρτωση σελίδων</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Σίγαση καρτελών</translation> <translation id="9040661932550800571">Ενημέρωση κωδικού πρόσβασης για <ph name="ORIGIN" />;</translation> <translation id="9041692268811217999">Η πρόσβαση στα τοπικά αρχεία στο μηχάνημά σας έχει απενεργοποιηθεί από το διαχειριστή σας</translation> <translation id="9042893549633094279">Απόρρητο και ασφάλεια</translation> @@ -5300,7 +5275,6 @@ <translation id="920045321358709304">Αναζήτηση <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Επιλογές κλειδώματος οθόνης</translation> <translation id="9203398526606335860">Ενεργοποιημένη &δυνατότητα δημιουργίας προφίλ</translation> -<translation id="9203478404496196495">Κατάργηση σίγασης καρτέλας</translation> <translation id="9203904171912129171">Επιλέξτε μια συσκευή</translation> <translation id="9203962528777363226">Ο διαχειριστής αυτής της συσκευής έχει απενεργοποιήσει την προσθήκη νέων χρηστών</translation> <translation id="9213073329713032541">Η εγκατάσταση ξεκίνησε με επιτυχία.</translation>
diff --git a/chrome/app/resources/generated_resources_en-GB.xtb b/chrome/app/resources/generated_resources_en-GB.xtb index 651a210..02dbe4e 100644 --- a/chrome/app/resources/generated_resources_en-GB.xtb +++ b/chrome/app/resources/generated_resources_en-GB.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Press ESCAPE to skip (Non-official builds only).</translation> <translation id="1093457606523402488">Visible Networks:</translation> <translation id="1094607894174825014">Read or write operation was requested with an invalid offset on: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">Unmute Sites</translation> <translation id="1097658378307015415">Before signing in, please enter as Guest to activate the network <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Always translate <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Stop</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Use the web without saving your browsing history with an incognito window</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> fingerprints set up</translation> <translation id="1215411991991485844">New background app added</translation> -<translation id="1216654534877302979">Mute Sites</translation> <translation id="1216659994753476700">We're sorry. We can't access your profile. Files and data stored on this device may have been lost.<ph name="BR" /> <ph name="BR" /> You'll have to set up your profile again.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Store data in your Google Drive account</translation> <translation id="1288037062697528143">Night Light will turn on automatically at sunset</translation> <translation id="1288300545283011870">Speech Properties</translation> -<translation id="1293177648337752319">Unmute Site</translation> <translation id="1293264513303784526">USB-C device (left port)</translation> <translation id="1293556467332435079">Files</translation> <translation id="1296497012903089238">Certificate Type</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Homepage is the New Tab page</translation> <translation id="1436671784520050284">Continue setup</translation> <translation id="1436784010935106834">Removed</translation> -<translation id="1438632560381091872">Unmute tabs</translation> <translation id="1442392616396121389">Routing prefix</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> selected</translation> <translation id="1444628761356461360">This setting is managed by the device owner, <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">A different keyboard has been connected since you last entered your password. It may be attempting to steal your keystrokes.</translation> <translation id="1567750922576943685">Verifying your identity helps protect your personal information</translation> <translation id="1567993339577891801">JavaScript Console</translation> -<translation id="1568067597247500137">Mute Site</translation> <translation id="1568323446248056064">Open display device settings</translation> <translation id="1572266655485775982">Wi-Fi enable</translation> <translation id="1572585716423026576">Set as wallpaper</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">X9.62 ECDSA Signature with SHA-1</translation> <translation id="1644574205037202324">History</translation> <translation id="1645516838734033527">To keep your <ph name="DEVICE_TYPE" /> safe, Smart Lock requires a screen lock on your phone.</translation> -<translation id="1646102270785326155">All files and local data associated with this user will be permanently deleted once this user is removed. $1 can still sign in later.</translation> <translation id="1646982517418478057">Please enter a password to encrypt this certificate</translation> <translation id="164814987133974965">A supervised user can explore the web with your guidance. As the manager of a supervised user, you can <ph name="BEGIN_BOLD" />allow or prohibit<ph name="END_BOLD" /> certain websites, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">It also controls what page is shown when you search from the Omnibox.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />To remove apps, go to Settings > Google Play Store > Manage Android preferences > Apps or Application manager. Then tap the app that you want to uninstall (you may need to swipe right or left to find the app). Then tap Uninstall or Disable.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Sending request...</translation> -<translation id="1732215134274276513">Unpin Tabs</translation> <translation id="1733383495376208985">Encrypt synced data with your own <ph name="BEGIN_LINK" />sync passphrase<ph name="END_LINK" />. This doesn't include payment methods and addresses from Google Pay.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> may not be able to keep itself updated</translation> <translation id="1736419249208073774">Explore</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">All files</translation> <translation id="1809734401532861917">Add my bookmarks, history, passwords and other settings to <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">No preview available</translation> -<translation id="1812631533912615985">Unpin tabs</translation> <translation id="1813278315230285598">Services</translation> <translation id="18139523105317219">EDI Party Name</translation> <translation id="1815083418640426271">Paste as Plain Text</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chrome is being controlled by automated test software.</translation> <translation id="2070909990982335904">Names starting with dot are reserved for the system. Please choose another name.</translation> <translation id="2071393345806050157">No local log file.</translation> -<translation id="2074527029802029717">Unpin tab</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% Battery</translation> <translation id="2075959085554270910">Allows you to enable/disable tap-to-click and tap dragging</translation> <translation id="2076269580855484719">Hide this plug-in</translation> @@ -1356,7 +1347,6 @@ <translation id="3045447014237878114">This site downloaded multiple files automatically</translation> <translation id="3046910703532196514">Web Page, Complete</translation> <translation id="304747341537320566">Speech Engines</translation> -<translation id="304826556400666995">Unmute Tabs</translation> <translation id="3053013834507634016">Certificate Key Usage</translation> <translation id="3057861065630527966">Backup your photos and videos</translation> <translation id="3060379269883947824">Enable Select to Speak</translation> @@ -2342,7 +2332,6 @@ <translation id="4628762811416793313">The Linux container setup did not complete. Please try again.</translation> <translation id="4628948037717959914">Photo</translation> <translation id="4631887759990505102">Artist</translation> -<translation id="4632483769545853758">Unmute Tab</translation> <translation id="4633003931260532286">Extension requires '<ph name="IMPORT_NAME" />' with a minimum version '<ph name="IMPORT_VERSION" />', but only version '<ph name="INSTALLED_VERSION" />' is installed</translation> <translation id="4634771451598206121">Sign in again...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> is not available to Guest users.</translation> @@ -2407,7 +2396,6 @@ <translation id="4736292055110123391">Sync your bookmarks, passwords, history and more on all your devices</translation> <translation id="4737715515457435632">Please connect to a network</translation> <translation id="473775607612524610">Update</translation> -<translation id="474217410105706308">Mute Tab</translation> <translation id="4742746985488890273">Pin to Shelf</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Find out how to update applications<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Messages</translation> @@ -2632,7 +2620,6 @@ <translation id="5094721898978802975">Communicate with cooperating native applications</translation> <translation id="5097002363526479830">Failed to connect to the network '<ph name="NAME" />': <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Open all bookmarks</translation> -<translation id="5105855035535475848">Pin tabs</translation> <translation id="5108967062857032718">Settings – Remove Android apps</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">&Bookmark Manager</translation> @@ -2697,7 +2684,6 @@ <translation id="520621735928254154">Certificate import error</translation> <translation id="5209320130288484488">No devices found</translation> <translation id="5209518306177824490">SHA-1 Fingerprint</translation> -<translation id="5210365745912300556">Close tab</translation> <translation id="5213481667492808996">Your '<ph name="NAME" />' data service is ready to use</translation> <translation id="5213891612754844763">Show proxy settings</translation> <translation id="521582610500777512">Photo was discarded</translation> @@ -2749,7 +2735,6 @@ <translation id="5272654297705279635">Custom settings</translation> <translation id="5275352920323889391">Dog</translation> <translation id="5275973617553375938">Recovered files from Google Drive</translation> -<translation id="527605719918376753">Mute tab</translation> <translation id="527605982717517565">Always allow JavaScript on <ph name="HOST" /></translation> <translation id="5280426389926346830">Create Shortcut?</translation> <translation id="528208740344463258">To download and use Android apps, first you need to install this required update. While your <ph name="DEVICE_TYPE" /> is updating, you can’t use it. After installation is complete, your <ph name="DEVICE_TYPE" /> will restart.</translation> @@ -2872,7 +2857,6 @@ <translation id="5449551289610225147">Invalid password</translation> <translation id="5449588825071916739">Bookmark All Tabs</translation> <translation id="5449716055534515760">Close Win&dow</translation> -<translation id="5453029940327926427">Close tabs</translation> <translation id="5454166040603940656">with <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Invalid</translation> <translation id="5457459357461771897">Read and delete photos, music and other media from your computer</translation> @@ -3337,7 +3321,6 @@ <translation id="6122875415561139701">Write operation is not permitted on: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">The following extensions depend on this extension:</translation> <translation id="6125479973208104919">Unfortunately, you'll need to add your account to this <ph name="DEVICE_TYPE" /> again.</translation> -<translation id="612596694132302162">Unmute Site</translation> <translation id="6129691635767514872">The selected data has been removed from Chrome and synced devices. Your Google Account may have other forms of browsing history such as searches and activity from other Google services at <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Netscape Certificate Comment</translation> <translation id="6129953537138746214">Space</translation> @@ -3540,7 +3523,6 @@ <translation id="6436164536244065364">View in Web Store</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – Audio playing</translation> <translation id="6442187272350399447">Happy</translation> -<translation id="6442697326824312960">Unpin Tab</translation> <translation id="6444070574980481588">Set date and time</translation> <translation id="6445450263907939268">If you didn't want these changes, you can restore your previous settings.</translation> <translation id="6447842834002726250">Cookies</translation> @@ -3743,7 +3725,6 @@ <translation id="6770664076092644100">Verify via NFC</translation> <translation id="6771503742377376720">Is a Certification Authority</translation> <translation id="6777817260680419853">Redirect blocked</translation> -<translation id="6778959797435875428">Unmute Sites</translation> <translation id="677965093459947883">Very small</translation> <translation id="6780439250949340171">manage other settings</translation> <translation id="6781284683813954823">Doodle Link</translation> @@ -4060,7 +4041,6 @@ <translation id="7257666756905341374">Read data that you copy and paste</translation> <translation id="7258697411818564379">Your PIN is added</translation> <translation id="7262004276116528033">This sign-in service is hosted by <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Close Tabs</translation> <translation id="7268659760406822741">Available services</translation> <translation id="7270858098575133036">Ask when a site wants to use system exclusive messages to access MIDI devices</translation> <translation id="7272674038937250585">No description provided</translation> @@ -4250,7 +4230,6 @@ <translation id="7576032389798113292">6 x 4</translation> <translation id="7576690715254076113">Collate</translation> <translation id="7576976045740938453">A problem with demo mode account occurred.</translation> -<translation id="7579149537961810247">Mute Sites</translation> <translation id="7580671184200851182">Play the same audio through all speakers (mono audio)</translation> <translation id="7581462281756524039">A cleanup tool</translation> <translation id="7582582252461552277">Prefer this network</translation> @@ -4604,7 +4583,6 @@ <translation id="8068253693380742035">Touch to sign in</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Print as image</translation> -<translation id="8072988827236813198">Pin Tabs</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />App data can be any data that an app has saved (based on developer settings), including data such as contacts, messages and photos.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Backup data will not count toward your child's Drive storage quota.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />You can turn this service off in Settings.<ph name="END_PARAGRAPH3" /></translation> @@ -4790,7 +4768,6 @@ <translation id="8368859634510605990">&Open all bookmarks</translation> <translation id="8371695176452482769">Speak now</translation> <translation id="8372369524088641025">Bad WEP key</translation> -<translation id="8373553483208508744">Mute tabs</translation> <translation id="8378714024927312812">Managed by your organisation</translation> <translation id="8379878387931047019">This device doesn't support the type of security key requested by this website</translation> <translation id="8382913212082956454">Copy &email address</translation> @@ -4898,7 +4875,6 @@ <translation id="8546930481464505581">Customise Touch Bar</translation> <translation id="8547013269961688403">Enable full-screen magnifier</translation> <translation id="85486688517848470">Hold the Search key to switch the behaviour of the top-row keys</translation> -<translation id="855081842937141170">Pin tab</translation> <translation id="8551388862522347954">Licences</translation> <translation id="8553342806078037065">Manage other people</translation> <translation id="8554899698005018844">No language</translation> @@ -5213,7 +5189,6 @@ <translation id="9038430547971207796">Next time, your phone will unlock your <ph name="DEVICE_TYPE" />. Turn off Smart Lock in Settings.</translation> <translation id="9038649477754266430">Use a prediction service to load pages more quickly</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Mute Tabs</translation> <translation id="9040661932550800571">Update password for <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Access to local files on your machine is disabled by your administrator</translation> <translation id="9042893549633094279">Privacy and security</translation> @@ -5311,7 +5286,6 @@ <translation id="920045321358709304">Search <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Screen lock options</translation> <translation id="9203398526606335860">&Profiling enabled</translation> -<translation id="9203478404496196495">Unmute tab</translation> <translation id="9203904171912129171">Select a device</translation> <translation id="9203962528777363226">The administrator of this device has disabled new users from being added</translation> <translation id="9213073329713032541">Installation successfully started.</translation>
diff --git a/chrome/app/resources/generated_resources_es-419.xtb b/chrome/app/resources/generated_resources_es-419.xtb index 22c975e..9c862ef7 100644 --- a/chrome/app/resources/generated_resources_es-419.xtb +++ b/chrome/app/resources/generated_resources_es-419.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Presiona ESCAPE para omitir (solo compilaciones no oficiales).</translation> <translation id="1093457606523402488">Redes visibles:</translation> <translation id="1094607894174825014">Se solicitó una operación de lectura o escritura con un intervalo no válido en: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">Activar el sonido de los sitios</translation> <translation id="1097658378307015415">Antes de acceder, ingresa como Invitado para activar la red <ph name="NETWORK_ID" />.</translation> <translation id="1103523840287552314">Siempre traducir <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Interrumpir</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Con una ventana de incógnito, podrás usar la Web sin que se guarde tu historial de navegación</translation> <translation id="1213037489357051291">Se configuraron <ph name="NUM_FINGERPRINTS" /> huellas digitales</translation> <translation id="1215411991991485844">Nueva aplicación en segundo plano agregada</translation> -<translation id="1216654534877302979">Silenciar los sitios</translation> <translation id="1216659994753476700">No podemos acceder a tu perfil. Es posible que se hayan perdido los archivos y datos almacenados en este dispositivo.<ph name="BR" /> <ph name="BR" /> Deberás configurar tu perfil nuevamente.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Almacenar datos en tu cuenta de Google Drive</translation> <translation id="1288037062697528143">La Luz nocturna se activará automáticamente al atardecer</translation> <translation id="1288300545283011870">Propiedades de comentarios de texto a voz</translation> -<translation id="1293177648337752319">Activar el sonido del sitio</translation> <translation id="1293264513303784526">Dispositivo USB-C (puerto izquierdo)</translation> <translation id="1293556467332435079">Archivos</translation> <translation id="1296497012903089238">Tipo de certificado</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">La página Nueva pestaña es la nueva página principal.</translation> <translation id="1436671784520050284">Continuar con la configuración</translation> <translation id="1436784010935106834">Eliminado</translation> -<translation id="1438632560381091872">Activar sonido de las pestañas</translation> <translation id="1442392616396121389">Prefijo de enrutamiento</translation> <translation id="144283815522798837">Cantidad seleccionada: <ph name="NUMBER_OF_ITEMS_SELECTED" /></translation> <translation id="1444628761356461360">Esta configuración es administrada por el propietario del dispositivo: <ph name="OWNER_EMAIL" />.</translation> @@ -385,7 +381,6 @@ <translation id="1567387640189251553">Se conectó otro teclado desde la última vez que ingresaste tu contraseña. Es posible que alguien esté intentando determinar qué teclas presionaste.</translation> <translation id="1567750922576943685">Para proteger tu información personal, verifica tu identidad</translation> <translation id="1567993339577891801">Consola de JavaScript</translation> -<translation id="1568067597247500137">Silenciar el sitio</translation> <translation id="1568323446248056064">Abrir configuración de pantalla</translation> <translation id="1572266655485775982">Habilitar Wi-Fi</translation> <translation id="1572585716423026576">Establecer como fondo de pantalla</translation> @@ -437,7 +432,6 @@ <translation id="1643072738649235303">Firma X9.62 ECDSA con SHA-1</translation> <translation id="1644574205037202324">Historial</translation> <translation id="1645516838734033527">Para mantener tu dispositivo <ph name="DEVICE_TYPE" /> protegido, Smart Lock requiere que agregues un bloqueo de pantalla en tu teléfono.</translation> -<translation id="1646102270785326155">Una vez que se quite este usuario, todos los archivos y datos locales asociados a él se borrarán de forma permanente. $1 puede acceder después.</translation> <translation id="1646982517418478057">Ingresa una contraseña para encriptar este certificado</translation> <translation id="164814987133974965">Un usuario supervisado puede explorar la Web con tu ayuda. Como administrador de un usuario supervisado, puedes <ph name="BEGIN_BOLD" />permitir o prohibir<ph name="END_BOLD" /> determinados sitios web, @@ -496,7 +490,6 @@ <translation id="1729533290416704613">También controla qué página se muestra al realizar búsquedas desde el cuadro multifunción.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Para quitar apps, ve a Configuración > Google Play Store > Administrar preferencias de Android > Apps o Administrador de aplicaciones. Luego, presiona la app que quieras desinstalar (es posible que debas deslizar el dedo hacia la derecha o la izquierda para encontrarla). A continuación, presiona Desinstalar o Inhabilitar.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Enviando solicitud...</translation> -<translation id="1732215134274276513">Desmarcar pestañas</translation> <translation id="1733383495376208985">Encriptar los datos sincronizados con tu propia <ph name="BEGIN_LINK" />frase de contraseña de sincronización<ph name="END_LINK" /> (no se incluyen formas de pago ni direcciones de Google Pay).</translation> <translation id="1734824808160898225">Es posible que <ph name="PRODUCT_NAME" /> no se mantenga actualizado</translation> <translation id="1736419249208073774">Explorar</translation> @@ -548,7 +541,6 @@ <translation id="1807938677607439181">Todos los archivos</translation> <translation id="1809734401532861917">Agregar mis favoritos, historial, contraseñas y otras opciones de configuración a <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Sin vista previa disponible</translation> -<translation id="1812631533912615985">Desmarcar pestañas</translation> <translation id="1813278315230285598">Servicios</translation> <translation id="18139523105317219">Nombre de parte EDI</translation> <translation id="1815083418640426271">Pegar como texto sin formato</translation> @@ -707,7 +699,6 @@ <translation id="2065405795449409761">Un software de prueba automatizado está controlando Chrome.</translation> <translation id="2070909990982335904">Los nombres que comienzan con un punto se reservan para el sistema. Elige otro nombre.</translation> <translation id="2071393345806050157">No hay ningún archivo de registro local.</translation> -<translation id="2074527029802029717">Anular fijación de pestaña</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% de batería</translation> <translation id="2075959085554270910">Te permite habilitar o inhabilitar las funciones de tocar para hacer clic y de tocar y arrastrar</translation> <translation id="2076269580855484719">Ocultar este complemento</translation> @@ -1349,7 +1340,6 @@ <translation id="3045447014237878114">Este sitio descargó varios archivos automáticamente</translation> <translation id="3046910703532196514">Página web, completa</translation> <translation id="304747341537320566">Motores de comentarios de texto a voz</translation> -<translation id="304826556400666995">Activar sonido de las pestañas</translation> <translation id="3053013834507634016">Uso de la clave del certificado</translation> <translation id="3057861065630527966">Crea una copia de seguridad de tus fotos y videos.</translation> <translation id="3060379269883947824">Habilitar Seleccionar para pronunciar</translation> @@ -2332,7 +2322,6 @@ <translation id="4628762811416793313">No se completó la configuración del contenedor de Linux. Vuelve a intentarlo.</translation> <translation id="4628948037717959914">Foto</translation> <translation id="4631887759990505102">Artista</translation> -<translation id="4632483769545853758">Activar sonido de la pestaña</translation> <translation id="4633003931260532286">La extensión requiere "<ph name="IMPORT_NAME" />" con la versión "<ph name="IMPORT_VERSION" />" como mínimo, pero solo está instalada la versión "<ph name="INSTALLED_VERSION" />"</translation> <translation id="4634771451598206121">Volver a acceder...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> no está disponible para los usuarios invitados.</translation> @@ -2396,7 +2385,6 @@ <translation id="4735803855089279419">El sistema no pudo determinar los identificadores de dispositivo para este dispositivo.</translation> <translation id="4737715515457435632">Conéctate a una red</translation> <translation id="473775607612524610">Actualizar</translation> -<translation id="474217410105706308">Silenciar pestaña</translation> <translation id="4742746985488890273">Fijar en la biblioteca</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Obtener información sobre cómo actualizar las aplicaciones<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Mensajes</translation> @@ -2621,7 +2609,6 @@ <translation id="5094721898978802975">Comunicarse con aplicaciones nativas en cooperación</translation> <translation id="5097002363526479830">Error al conectar a la red "<ph name="NAME" />": <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Abrir todos los favoritos</translation> -<translation id="5105855035535475848">Marcar pestañas</translation> <translation id="5108967062857032718">Configuración - Quitar las apps de Android</translation> <translation id="5109044022078737958">Victoria</translation> <translation id="5111692334209731439">Adminis&trador de favoritos</translation> @@ -2686,7 +2673,6 @@ <translation id="520621735928254154">Error en la importación de certificado</translation> <translation id="5209320130288484488">No se encontraron dispositivos.</translation> <translation id="5209518306177824490">Huella digital SHA-1</translation> -<translation id="5210365745912300556">Cerrar pestaña</translation> <translation id="5213481667492808996">Ya puedes usar tu servicio de datos de "<ph name="NAME" />"</translation> <translation id="5213891612754844763">Mostrar la configuración de proxy</translation> <translation id="521582610500777512">Se descartó la foto.</translation> @@ -2737,7 +2723,6 @@ <translation id="5270167208902136840">Mostrar <ph name="NUMBER_OF_MORE_APPS" /> apps más</translation> <translation id="5275352920323889391">Perro</translation> <translation id="5275973617553375938">Archivos recuperados de Google Drive</translation> -<translation id="527605719918376753">Silenciar pestaña</translation> <translation id="527605982717517565">Siempre permitir JavaScript en <ph name="HOST" /></translation> <translation id="5280426389926346830">¿Deseas crear un acceso directo?</translation> <translation id="528208740344463258">Para descargar y usar las apps de Android, debes instalar esta actualización obligatoria. No puedes usar tu <ph name="DEVICE_TYPE" /> mientras se actualiza. Tu <ph name="DEVICE_TYPE" /> se reiniciará cuando se haya completado la instalación.</translation> @@ -2860,7 +2845,6 @@ <translation id="5449551289610225147">Contraseña no válida</translation> <translation id="5449588825071916739">Agregar a favoritos todas las pestañas</translation> <translation id="5449716055534515760">Cerrar ven&tana</translation> -<translation id="5453029940327926427">Cerrar pestañas</translation> <translation id="5454166040603940656">con <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Sin validez</translation> <translation id="5457459357461771897">Leer y eliminar fotos, música y otro contenido multimedia desde tu computadora</translation> @@ -3325,7 +3309,6 @@ <translation id="6122875415561139701">No se permite la operación de escritura en: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">Las siguientes extensiones dependen de esta extensión:</translation> <translation id="6125479973208104919">Lamentablemente, debes volver a agregar tu cuenta a este dispositivo <ph name="DEVICE_TYPE" />.</translation> -<translation id="612596694132302162">Activar el sonido del sitio</translation> <translation id="6129691635767514872">Los datos seleccionados se quitaron de Chrome y los dispositivos sincronizados. Es posible que tu cuenta de Google tenga otros formularios del historial de navegación, como las búsquedas y la actividad de otros servicios de Google en <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Comentario sobre el certificado Netscape</translation> <translation id="6129953537138746214">Google Space</translation> @@ -3528,7 +3511,6 @@ <translation id="6436164536244065364">Ver en Web Store</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" />: Reproducción de audio</translation> <translation id="6442187272350399447">Impresionante</translation> -<translation id="6442697326824312960">Anular fijación de pestaña</translation> <translation id="6444070574980481588">Establecer fecha y hora</translation> <translation id="6445450263907939268">Si no querías realizar estos cambios, puedes restablecer la configuración previa.</translation> <translation id="6447842834002726250">Cookies</translation> @@ -3731,7 +3713,6 @@ <translation id="6770664076092644100">Verificar mediante NFC</translation> <translation id="6771503742377376720">Es una Entidad de certificación</translation> <translation id="6777817260680419853">Se bloqueó el redireccionamiento</translation> -<translation id="6778959797435875428">Activar el sonido de los sitios</translation> <translation id="677965093459947883">Muy pequeño</translation> <translation id="6780439250949340171">administrar otros parámetros de configuración</translation> <translation id="6781284683813954823">Vínculo al doodle</translation> @@ -4048,7 +4029,6 @@ <translation id="7257666756905341374">Leer los datos que copias y pegas</translation> <translation id="7258697411818564379">Se agregó tu PIN</translation> <translation id="7262004276116528033">El servicio de acceso a la cuenta está alojado en <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Cerrar pestañas</translation> <translation id="7268659760406822741">Servicios disponibles</translation> <translation id="7270858098575133036">Preguntarme cuando un sitio quiera usar los mensajes exclusivos del sistema para acceder a dispositivos MIDI</translation> <translation id="7272674038937250585">No se proporcionó ninguna descripción</translation> @@ -4238,7 +4218,6 @@ <translation id="7576032389798113292">6 x 4</translation> <translation id="7576690715254076113">Intercalar</translation> <translation id="7576976045740938453">Hubo un problema con la cuenta en el modo de demostración.</translation> -<translation id="7579149537961810247">Silenciar los sitios</translation> <translation id="7580671184200851182">Reproducir el mismo audio en todos los altavoces (sonido mono)</translation> <translation id="7581462281756524039">Una herramienta de limpieza</translation> <translation id="7582582252461552277">Preferir esta red</translation> @@ -4592,7 +4571,6 @@ <translation id="8068253693380742035">Tocar para acceder</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Imprimir como imagen</translation> -<translation id="8072988827236813198">Marcar pestañas</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Los datos de las apps pueden incluir cualquier información que haya guardado una app (en función de la configuración del desarrollador), incluso datos como contactos, mensajes y fotos.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Los datos de la copia de seguridad no inciden en la cuota de almacenamiento en Drive de tu hijo.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Se puede desactivar este servicio en Configuración.<ph name="END_PARAGRAPH3" /></translation> @@ -4779,7 +4757,6 @@ <translation id="8368859634510605990">&Abrir todos los favoritos</translation> <translation id="8371695176452482769">Hablar ahora</translation> <translation id="8372369524088641025">Clave de WEP no válida</translation> -<translation id="8373553483208508744">Silenciar pestañas</translation> <translation id="8378714024927312812">Administrado por tu organización</translation> <translation id="8379878387931047019">Este dispositivo no es compatible con el tipo de llave de seguridad que se solicita en este sitio web</translation> <translation id="8382913212082956454">Copiar dir&ección de correo electrónico</translation> @@ -4887,7 +4864,6 @@ <translation id="8546930481464505581">Personalizar la barra táctil</translation> <translation id="8547013269961688403">Habilitar lupa en pantalla completa</translation> <translation id="85486688517848470">Mantén presionada la tecla de búsqueda para cambiar el comportamiento de las teclas en la fila superior</translation> -<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> @@ -5201,7 +5177,6 @@ <translation id="9038430547971207796">La próxima vez, tu teléfono desbloqueará tu <ph name="DEVICE_TYPE" />. Desactiva Smart Lock en la Configuración.</translation> <translation id="9038649477754266430">Utilizar un servicio de predicción para cargar las páginas más rápido</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Silenciar pestañas</translation> <translation id="9040661932550800571">¿Quieres actualizar la contraseña para <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Tu administrador bloqueó el acceso a los archivos locales en tu máquina</translation> <translation id="9042893549633094279">Privacidad y seguridad</translation> @@ -5299,7 +5274,6 @@ <translation id="920045321358709304">Buscar en <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Opciones de bloqueo de pantalla</translation> <translation id="9203398526606335860">&Perfiles activados</translation> -<translation id="9203478404496196495">Activar sonido de la pestaña</translation> <translation id="9203904171912129171">Seleccionar un dispositivo</translation> <translation id="9203962528777363226">El administrador de este dispositivo ha inhabilitado a nuevos usuarios para evitar que se agreguen.</translation> <translation id="9213073329713032541">La instalación se inició de forma correcta.</translation>
diff --git a/chrome/app/resources/generated_resources_es.xtb b/chrome/app/resources/generated_resources_es.xtb index d06c0a03..c066a8d 100644 --- a/chrome/app/resources/generated_resources_es.xtb +++ b/chrome/app/resources/generated_resources_es.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Pulsa Esc para omitir este paso (solo para compilaciones no oficiales).</translation> <translation id="1093457606523402488">Redes visibles:</translation> <translation id="1094607894174825014">La operación de lectura o escritura se ha solicitado con una variación no válida de "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">Activar sonido de sitios web</translation> <translation id="1097658378307015415">Antes de iniciar sesión, entra como invitado para activar la red <ph name="NETWORK_ID" />.</translation> <translation id="1103523840287552314">Traducir siempre del <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Detener</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Navega por Internet sin guardar tu historial de navegación con una ventana de incógnito</translation> <translation id="1213037489357051291">Número de huellas digitales configuradas: <ph name="NUM_FINGERPRINTS" /></translation> <translation id="1215411991991485844">Nueva aplicación en segundo plano añadida</translation> -<translation id="1216654534877302979">Silenciar sitios web</translation> <translation id="1216659994753476700">Lo sentimos. No podemos acceder a tu perfil. Es posible que los archivos y los datos almacenados en este dispositivo se hayan perdido.<ph name="BR" /> <ph name="BR" /> Debes volver a configurar tu perfil.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Almacenar datos en tu cuenta de Google Drive</translation> <translation id="1288037062697528143">La luz nocturna se activará automáticamente al anochecer</translation> <translation id="1288300545283011870">Propiedades de voz</translation> -<translation id="1293177648337752319">Activar sonido del sitio web</translation> <translation id="1293264513303784526">Dispositivo USB-C (puerto izquierdo)</translation> <translation id="1293556467332435079">Archivos</translation> <translation id="1296497012903089238">Tipo de certificado</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">La página de inicio es la página Nueva pestaña</translation> <translation id="1436671784520050284">Continuar con la configuración</translation> <translation id="1436784010935106834">Eliminado</translation> -<translation id="1438632560381091872">Activar sonido de pestañas</translation> <translation id="1442392616396121389">Prefijo de enrutamiento</translation> <translation id="144283815522798837">Elementos seleccionados: <ph name="NUMBER_OF_ITEMS_SELECTED" /></translation> <translation id="1444628761356461360">Esta opción está administrada por el propietario del dispositivo, <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Se ha conectado otro teclado desde la última vez que introdujiste la contraseña. Es posible que esté intentando captar tus pulsaciones de teclas.</translation> <translation id="1567750922576943685">Verificar tu identidad ayuda a proteger tu información personal</translation> <translation id="1567993339577891801">Consola JavaScript</translation> -<translation id="1568067597247500137">Silenciar sitio web</translation> <translation id="1568323446248056064">Abrir la configuración de la pantalla</translation> <translation id="1572266655485775982">Habilitar Wi-Fi</translation> <translation id="1572585716423026576">Configurar como fondo de pantalla</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">Firma X9.62 ECDSA con SHA-1</translation> <translation id="1644574205037202324">Historial</translation> <translation id="1645516838734033527">Para mantener tu <ph name="DEVICE_TYPE" /> protegido, Smart Lock necesita que el teléfono tenga configurado el bloqueo de pantalla.</translation> -<translation id="1646102270785326155">Una vez que se haya quitado este usuario, todos los archivos y datos asociados a él se eliminarán de forma permanente. $1 igualmente puede iniciar sesión más tarde.</translation> <translation id="1646982517418478057">Introduce una contraseña para cifrar este certificado</translation> <translation id="164814987133974965">Un usuario supervisado puede explorar la Web con tu ayuda. Como administrador de un usuario supervisado, puedes realizar las siguientes acciones: <ph name="BEGIN_BOLD" />permitir o prohibir<ph name="END_BOLD" /> ciertos sitios web, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">También controla qué página se muestra al hacer búsquedas desde el omnibox.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Para desinstalar aplicaciones, ve a Ajustes > Google Play Store > Gestionar las preferencias de Android > Aplicaciones o Administrador de aplicaciones. A continuación, toca la aplicación que quieras desinstalar (es posible que tengas que deslizar el dedo hacia la derecha o la izquierda para encontrar la aplicación) y Desinstalar o Inhabilitar.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Enviando solicitud...</translation> -<translation id="1732215134274276513">No fijar pestañas</translation> <translation id="1733383495376208985">Cifra los datos sincronizados con tu propia <ph name="BEGIN_LINK" />frase de contraseña de sincronización<ph name="END_LINK" />. El cifrado no incluye los métodos de pago ni las direcciones de Google Pay.</translation> <translation id="1734824808160898225">Es posible que <ph name="PRODUCT_NAME" /> no se pueda mantener actualizado</translation> <translation id="1736419249208073774">Más información</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Todos los archivos</translation> <translation id="1809734401532861917">Añadir mis marcadores, mi historial, mis contraseñas y otras opciones de configuración a <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">No hay vistas previas disponibles</translation> -<translation id="1812631533912615985">No fijar pestañas</translation> <translation id="1813278315230285598">Servicios</translation> <translation id="18139523105317219">Nombre de parte EDI</translation> <translation id="1815083418640426271">Pegar como texto sin formato</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Un software automatizado de pruebas está controlando Chrome.</translation> <translation id="2070909990982335904">Los nombres que empiezan por punto están reservados para el sistema. Elige otro nombre.</translation> <translation id="2071393345806050157">No hay ningún archivo de registro local.</translation> -<translation id="2074527029802029717">No fijar pestaña</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% de batería</translation> <translation id="2075959085554270910">Te permite habilitar o inhabilitar las funciones tocar para hacer clic y tocar y arrastrar</translation> <translation id="2076269580855484719">Ocultar este complemento</translation> @@ -773,6 +764,7 @@ <translation id="215753907730220065">Desactivar pantalla completa</translation> <translation id="2157875535253991059">Esta página se muestra ahora en pantalla completa.</translation> <translation id="216169395504480358">Añadir Wi-Fi...</translation> +<translation id="2162155940152307086">La sincronización empezará cuando salgas de la configuración</translation> <translation id="2163470535490402084">Conéctate a Internet para iniciar sesión en tu <ph name="DEVICE_TYPE" />.</translation> <translation id="2166369534954157698">Benjamín pidió una bebida de kiwi y fresa. Noé, sin vergüenza, la más exquisita champaña del menú.</translation> <translation id="2169062631698640254">Iniciar sesión de todas formas</translation> @@ -783,6 +775,7 @@ <translation id="2178098616815594724">El complemento <ph name="PEPPER_PLUGIN_NAME" /> de <ph name="PEPPER_PLUGIN_DOMAIN" /> quiere acceder a tu ordenador</translation> <translation id="2178614541317717477">Compromiso de entidad emisora de certificados</translation> <translation id="218070003709087997">Usa un número para indicar cuántas copias quieres imprimir (entre 1 y 999).</translation> +<translation id="2182253583899676504">El texto que escribas en los campos de texto se enviará a Google.</translation> <translation id="2184515124301515068">Permitir que Chrome elija cuándo los sitios web pueden reproducir sonidos (recomendado)</translation> <translation id="2187895286714876935">Error de importación del certificado de servidor</translation> <translation id="2187906491731510095">Se han actualizado las extensiones</translation> @@ -794,7 +787,9 @@ <translation id="2192505247865591433">De:</translation> <translation id="2193365732679659387">Configuración de confianza</translation> <translation id="2195729137168608510">Protección de correo electrónico</translation> +<translation id="2198757192731523470">Es posible que se utilice tu historial para personalizar la Búsqueda, los anuncios y otros servicios de Google.</translation> <translation id="2199298570273670671">Error</translation> +<translation id="2199719347983604670">Datos de Sincronización de Chrome</translation> <translation id="2200094388063410062">Correo electrónico</translation> <translation id="2200356397587687044">Chrome necesita permiso para continuar</translation> <translation id="2200603218210188859">Preferencias de dispositivos USB</translation> @@ -1252,6 +1247,7 @@ <translation id="2889064240420137087">Abrir enlace con...</translation> <translation id="2889925978073739256">Seguir bloqueando complementos no incluidos en la zona de pruebas</translation> <translation id="2893168226686371498">Navegador predeterminado</translation> +<translation id="2895734772884435517">Puedes personalizar la configuración en cualquier momento.</translation> <translation id="289644616180464099">La tarjeta SIM está bloqueada</translation> <translation id="289695669188700754">ID de clave: <ph name="KEY_ID" /></translation> <translation id="2897878306272793870">¿Seguro que quieres abrir <ph name="TAB_COUNT" /> pestañas?</translation> @@ -1352,7 +1348,6 @@ <translation id="3045447014237878114">Este sitio web ha descargado varios archivos automáticamente</translation> <translation id="3046910703532196514">Página web (completa)</translation> <translation id="304747341537320566">Motores de voz</translation> -<translation id="304826556400666995">Activar sonido de pestañas</translation> <translation id="3053013834507634016">Uso de claves de certificado</translation> <translation id="3057861065630527966">Realiza copias de seguridad de tus fotos y vídeos</translation> <translation id="3060379269883947824">Habilitar Enunciar Selección</translation> @@ -1719,6 +1714,7 @@ <translation id="3636096452488277381">Hola, <ph name="USER_GIVEN_NAME" />.</translation> <translation id="3636766455281737684"><ph name="PERCENTAGE" />% - <ph name="TIME" /> hasta agotar la batería</translation> <translation id="3637682276779847508">La tarjeta SIM se inhabilitará de forma permanente si no introduces el código PUK correcto.</translation> +<translation id="363863692969456324">Corrige errores ortográficos con la revisión ortográfica mejorada</translation> <translation id="3640214691812501263">¿Añadir <ph name="EXTENSION_NAME" /> para <ph name="USER_NAME" />?</translation> <translation id="3644896802912593514">Anchura</translation> <translation id="3645372836428131288">Mueve el dedo ligeramente para capturar otra parte de la huella digital.</translation> @@ -2150,6 +2146,7 @@ <translation id="4310139701823742692">El formato del archivo no es correcto. Comprueba el archivo PPD e inténtalo de nuevo.</translation> <translation id="431076611119798497">&Detalles</translation> <translation id="4312866146174492540">Bloquear (predeterminado)</translation> +<translation id="4314815835985389558">Gestionar la sincronización</translation> <translation id="4316850752623536204">Sitio web del desarrollador</translation> <translation id="4320177379694898372">No hay conexión a Internet</translation> <translation id="4320948194796820126">Añade un marcador a tu correo electrónico</translation> @@ -2229,6 +2226,7 @@ <translation id="4450974146388585462">Diagnosticar</translation> <translation id="4451757071857432900">Bloqueados en sitios web que muestran anuncios invasivos o engañosos (opción recomendada)</translation> <translation id="4453946976636652378">Busca <ph name="SEARCH_ENGINE_NAME" /> o introduce una URL</translation> +<translation id="4461835665417498653">Envía a Google información del sistema y contenido de las páginas de forma anónima.</translation> <translation id="4462159676511157176">Servidores de nombres personalizados</translation> <translation id="4467101674048705704">Mostrar <ph name="FOLDER_NAME" /></translation> <translation id="4469477701382819144">Bloqueados en sitios web que muestran anuncios invasivos o engañosos</translation> @@ -2332,7 +2330,6 @@ <translation id="4628762811416793313">La configuración del contenedor de Linux no se ha completado. Inténtalo de nuevo.</translation> <translation id="4628948037717959914">Foto</translation> <translation id="4631887759990505102">Artista</translation> -<translation id="4632483769545853758">Activar sonido de pestaña</translation> <translation id="4633003931260532286">La extensión necesita "<ph name="IMPORT_NAME" />" con la versión "<ph name="IMPORT_VERSION" />" como mínimo, pero solo está instalada la versión "<ph name="INSTALLED_VERSION" />".</translation> <translation id="4634771451598206121">Volver a iniciar sesión...</translation> <translation id="4635398712689569051">La página <ph name="PAGE_NAME" /> no está disponible para los usuarios invitados.</translation> @@ -2394,9 +2391,9 @@ <translation id="4735265153267957659">Introduce tu contraseña para habilitar Smart Lock. La próxima vez, el teléfono desbloqueará tu <ph name="DEVICE_TYPE" />. Puedes desactivar Smart Lock en la configuración.</translation> <translation id="473546211690256853">Esta cuenta está administrada por <ph name="DOMAIN" /></translation> <translation id="4735803855089279419">El sistema no ha podido determinar los identificadores de este dispositivo.</translation> +<translation id="4736292055110123391">Sincroniza tus marcadores, tus contraseñas, tu historial y mucho más en todos tus dispositivos</translation> <translation id="4737715515457435632">Establece conexión con una red</translation> <translation id="473775607612524610">Actualizar</translation> -<translation id="474217410105706308">Silenciar pestaña</translation> <translation id="4742746985488890273">Fijar en la estantería</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Cómo actualizar aplicaciones<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Mensajes</translation> @@ -2621,7 +2618,6 @@ <translation id="5094721898978802975">Comunicarse con aplicaciones nativas cooperativas</translation> <translation id="5097002363526479830">Error al establecer conexión con la red "<ph name="NAME" />": <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Abrir todos los marcadores</translation> -<translation id="5105855035535475848">Fijar pestañas</translation> <translation id="5108967062857032718">Configuración - Quitar aplicaciones de Android</translation> <translation id="5109044022078737958">Atleta</translation> <translation id="5111692334209731439">&Administrador de marcadores</translation> @@ -2686,7 +2682,6 @@ <translation id="520621735928254154">Error al importar el certificado</translation> <translation id="5209320130288484488">No se ha encontrado ningún dispositivo.</translation> <translation id="5209518306177824490">Huella digital SHA-1</translation> -<translation id="5210365745912300556">Cerrar pestaña</translation> <translation id="5213481667492808996">Ya puedes usar tu servicio de datos de "<ph name="NAME" />"</translation> <translation id="5213891612754844763">Mostrar configuración de proxy</translation> <translation id="521582610500777512">Se ha descartado la foto</translation> @@ -2735,9 +2730,9 @@ <translation id="5266113311903163739">Error de importación de la entidad emisora de certificados</translation> <translation id="5269977353971873915">Error de impresión</translation> <translation id="5270167208902136840">Mostrar <ph name="NUMBER_OF_MORE_APPS" /> aplicaciones más</translation> +<translation id="5272654297705279635">Configuración personalizada</translation> <translation id="5275352920323889391">Perro</translation> <translation id="5275973617553375938">Archivos recuperados de Google Drive</translation> -<translation id="527605719918376753">Silenciar pestaña</translation> <translation id="527605982717517565">Permitir siempre JavaScript en <ph name="HOST" /></translation> <translation id="5280426389926346830">¿Quieres crear un acceso directo?</translation> <translation id="528208740344463258">Para descargar y utilizar aplicaciones de Android, primero debes instalar esta actualización. Mientras se actualiza tu <ph name="DEVICE_TYPE" />, no podrás usarlo. Tu <ph name="DEVICE_TYPE" /> se reiniciará cuando se complete la instalación.</translation> @@ -2860,7 +2855,6 @@ <translation id="5449551289610225147">La contraseña no es válida</translation> <translation id="5449588825071916739">Añadir todas las pestañas a marcadores...</translation> <translation id="5449716055534515760">Cerrar &ventana</translation> -<translation id="5453029940327926427">Cerrar pestañas</translation> <translation id="5454166040603940656">con <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">No válido</translation> <translation id="5457459357461771897">Leer y eliminar fotos, música y otros archivos multimedia de tu ordenador</translation> @@ -3325,7 +3319,6 @@ <translation id="6122875415561139701">No se permite la operación de escritura en "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">Las siguientes extensiones dependen de esta extensión:</translation> <translation id="6125479973208104919">Debes volver a añadir una cuenta a este <ph name="DEVICE_TYPE" />.</translation> -<translation id="612596694132302162">Activar sonido del sitio web</translation> <translation id="6129691635767514872">Los datos seleccionados se han quitado de Chrome y de los dispositivos sincronizados. Es posible que tu cuenta de Google tenga otros tipos de historial de navegación, como búsquedas o actividad de otros servicios de Google, en la página <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Comentario del certificado de Netscape</translation> <translation id="6129953537138746214">Espacio</translation> @@ -3528,7 +3521,6 @@ <translation id="6436164536244065364">Ver en Web Store</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" />: reproducción de audio</translation> <translation id="6442187272350399447">Impresionante</translation> -<translation id="6442697326824312960">No fijar pestaña</translation> <translation id="6444070574980481588">Establecer fecha y hora</translation> <translation id="6445450263907939268">Si no querías realizar estos cambios, puedes restaurar la configuración anterior.</translation> <translation id="6447842834002726250">Cookies</translation> @@ -3731,7 +3723,6 @@ <translation id="6770664076092644100">Verificar mediante NFC</translation> <translation id="6771503742377376720">Es una entidad emisora de certificados.</translation> <translation id="6777817260680419853">Redirección bloqueada</translation> -<translation id="6778959797435875428">Activar sonido de sitios web</translation> <translation id="677965093459947883">Muy pequeño</translation> <translation id="6780439250949340171">administrar otras opciones.</translation> <translation id="6781284683813954823">Enlace del doodle</translation> @@ -4048,7 +4039,6 @@ <translation id="7257666756905341374">Leer los datos que copias y pegas</translation> <translation id="7258697411818564379">Se ha añadido el PIN</translation> <translation id="7262004276116528033">Este servicio de inicio de sesión está alojado por <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Cerrar pestañas</translation> <translation id="7268659760406822741">Servicios disponibles</translation> <translation id="7270858098575133036">Preguntar cuando un sitio web quiera utilizar mensajes exclusivos del sistema para acceder a los dispositivos MIDI</translation> <translation id="7272674038937250585">No se ha especificado ninguna descripción</translation> @@ -4238,7 +4228,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">Intercalar</translation> <translation id="7576976045740938453">Ha habido un problema con la cuenta del modo de demostración.</translation> -<translation id="7579149537961810247">Silenciar sitios web</translation> <translation id="7580671184200851182">Reproducir el mismo audio en todos los altavoces (audio mono)</translation> <translation id="7581462281756524039">Una herramienta de limpieza</translation> <translation id="7582582252461552277">Establecer esta red como preferida</translation> @@ -4592,7 +4581,6 @@ <translation id="8068253693380742035">Toca para iniciar sesión</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Imprimir como imagen</translation> -<translation id="8072988827236813198">Fijar pestañas</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Los datos de aplicaciones pueden ser cualquier tipo de información que guarden las aplicaciones (según la configuración de los desarrolladores), como contactos, mensajes y fotos.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Los datos de la copia de seguridad no se tienen en cuenta para calcular el espacio de almacenamiento de la cuenta de Google Drive de tu hijo.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Puedes desactivar este servicio en Ajustes.<ph name="END_PARAGRAPH3" /></translation> @@ -4778,7 +4766,6 @@ <translation id="8368859634510605990">&Abrir todos los marcadores</translation> <translation id="8371695176452482769">Habla ahora</translation> <translation id="8372369524088641025">Clave WEP incorrecta</translation> -<translation id="8373553483208508744">Silenciar pestañas</translation> <translation id="8378714024927312812">Gestionado por tu organización</translation> <translation id="8379878387931047019">Este dispositivo no es compatible con el tipo de llave de seguridad solicitado por el sitio web</translation> <translation id="8382913212082956454">Copiar dir&ección de correo electrónico</translation> @@ -4886,7 +4873,6 @@ <translation id="8546930481464505581">Personalizar la barra táctil</translation> <translation id="8547013269961688403">Habilitar lupa de pantalla completa</translation> <translation id="85486688517848470">Mantén pulsada la tecla de búsqueda para cambiar el comportamiento de las teclas de la fila superior</translation> -<translation id="855081842937141170">Fijar pestaña</translation> <translation id="8551388862522347954">Licencias</translation> <translation id="8553342806078037065">Administrar otros usuarios</translation> <translation id="8554899698005018844">Sin idioma</translation> @@ -4916,6 +4902,7 @@ <translation id="8598453409908276158">Complemento no incluido en la zona de pruebas bloqueado</translation> <translation id="8601206103050338563">Autenticación de cliente WWW TLS</translation> <translation id="8602851771975208551">Otro programa de tu ordenador ha añadido una aplicación que puede cambiar el funcionamiento de Chrome.</translation> +<translation id="8604763363205185560">Ayuda a mejorar Chrome y su seguridad</translation> <translation id="8605428685123651449">Memoria SQLite</translation> <translation id="8606726445206553943">Utilizar tus dispositivos MIDI</translation> <translation id="8609465669617005112">Subir</translation> @@ -5200,7 +5187,6 @@ <translation id="9038430547971207796">La próxima vez, el teléfono desbloqueará tu <ph name="DEVICE_TYPE" />. Desactiva Smart Lock en Configuración.</translation> <translation id="9038649477754266430">Utilizar un servicio de predicciones para que las páginas se carguen más rápido</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Silenciar pestañas</translation> <translation id="9040661932550800571">¿Quieres actualizar la contraseña de <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Tu administrador ha inhabilitado el acceso a los archivos locales de tu equipo</translation> <translation id="9042893549633094279">Privacidad y seguridad</translation> @@ -5298,7 +5284,6 @@ <translation id="920045321358709304">Buscar con <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Opciones de bloqueo de pantalla</translation> <translation id="9203398526606335860">&Perfiles habilitados</translation> -<translation id="9203478404496196495">Activar sonido de pestaña</translation> <translation id="9203904171912129171">Selecciona un dispositivo</translation> <translation id="9203962528777363226">El administrador de este dispositivo ha desactivado la opción de añadir nuevos usuarios.</translation> <translation id="9213073329713032541">Se ha iniciado la instalación correctamente.</translation>
diff --git a/chrome/app/resources/generated_resources_et.xtb b/chrome/app/resources/generated_resources_et.xtb index e1c0a27..1401b66 100644 --- a/chrome/app/resources/generated_resources_et.xtb +++ b/chrome/app/resources/generated_resources_et.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Vahelejätmiseks vajutage klahvi ESC (ainult mitteametlike järkude puhul).</translation> <translation id="1093457606523402488">Nähtavad võrgud:</translation> <translation id="1094607894174825014">Lugemise või kirjutamise toimingut taotleti sobimatu nihkega seadmes „<ph name="DEVICE_NAME" />”.</translation> -<translation id="109758035718544977">Tühista saitide vaigistus</translation> <translation id="1097658378307015415">Enne sisselogimist sisenege võrgu <ph name="NETWORK_ID" /> aktiveerimiseks külastajana</translation> <translation id="1103523840287552314">Tõlgi alati: <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Peata</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Inkognito aknas kasutate veebi ilma sirvimisajalugu salvestamata</translation> <translation id="1213037489357051291">Seadistati <ph name="NUM_FINGERPRINTS" /> sõrmejälg(e)</translation> <translation id="1215411991991485844">Uus taustarakendus on lisatud</translation> -<translation id="1216654534877302979">Vaigista saidid</translation> <translation id="1216659994753476700">Vabandust! Me ei pääse teie profiilile juurde. Sellesse seadmesse salvestatud failid ja andmed võivad olla kaotsi läinud.<ph name="BR" /> <ph name="BR" /> Peate oma profiili uuesti seadistama.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Salvestage andmed oma Google Drive'i kontole</translation> <translation id="1288037062697528143">Funktsioon Öövalgus lülitub automaatselt sisse päikeseloojangul</translation> <translation id="1288300545283011870">Kõne atribuudid</translation> -<translation id="1293177648337752319">Tühista saidi vaigistus</translation> <translation id="1293264513303784526">C-tüüpi USB-seade (vasakpoolne port)</translation> <translation id="1293556467332435079">Failid</translation> <translation id="1296497012903089238">Sertifikaadi tüüp</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Avaleht on uus vaheleht</translation> <translation id="1436671784520050284">Jätka seadistamist</translation> <translation id="1436784010935106834">Eemaldatud</translation> -<translation id="1438632560381091872">Tühista vahekaartide summutus</translation> <translation id="1442392616396121389">Marsruutimise eesliide</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> on valitud</translation> <translation id="1444628761356461360">Seadet haldab seadme omanik <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Pärast parooli viimast sisestamist on ühendatud teine klaviatuur. See võib üritada varastada teie klahvivajutusi.</translation> <translation id="1567750922576943685">Teie identiteedi kinnitamine aitab teie isiklikke andmeid kaitsta</translation> <translation id="1567993339577891801">JavaScripti konsool</translation> -<translation id="1568067597247500137">Vaigista sait</translation> <translation id="1568323446248056064">Kuvaseadme seadete avamine</translation> <translation id="1572266655485775982">WiFi lubamine</translation> <translation id="1572585716423026576">Taustapildiks määramine</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">X9.62 ECDSA allkiri SHA-1-ga</translation> <translation id="1644574205037202324">Ajalugu</translation> <translation id="1645516838734033527">Seadme <ph name="DEVICE_TYPE" /> turvalisuse tagamiseks nõuab Smart Lock teie telefonis ekraanilukku.</translation> -<translation id="1646102270785326155">Kõik selle kasutajaga seotud failid ja kohalikud andmed kustutatakse jäädavalt kohe, kui see kasutaja eemaldatakse. $1 saab siiski hiljem sisse logida.</translation> <translation id="1646982517418478057">Sisestage parool selle sertifikaadi krüpteerimiseks</translation> <translation id="164814987133974965">Jälgitav kasutaja saab kasutada veebi teie juhiste järgi. Jälgitava kasutaja haldurina saate teha järgmist: <ph name="BEGIN_BOLD" />lubada või keelata<ph name="END_BOLD" /> teatud veebisaidid; @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Lisaks juhib omnikastikeses otsingu tegemise lehte.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Rakenduste eemaldamiseks avage menüü Seaded> Google Play pood > Androidi eelistuste haldamine > Rakendused või Rakenduste haldur. Seejärel puudutage rakendust, mille soovite desinstallida (rakenduse leidmiseks peate võib-olla paremale või vasakule pühkima). Seejärel puudutage käsku Desinstalli või Keela.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Päringu saatmine...</translation> -<translation id="1732215134274276513">Vabasta vahelehed</translation> <translation id="1733383495376208985">Krüpteerige sünkroonitud andmed <ph name="BEGIN_LINK" />sünkroonimisparooliga<ph name="END_LINK" />. See ei hõlma Google Pay makseviise ja aadresse.</translation> <translation id="1734824808160898225">Võimalik, et teenusel <ph name="PRODUCT_NAME" /> ei õnnestu ennast värskendada</translation> <translation id="1736419249208073774">Avastage</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Kõik failid</translation> <translation id="1809734401532861917">Lisa minu järjehoidjad, ajalugu, paroolid ja muud seaded e-posti aadressile <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Eelvaade pole saadaval</translation> -<translation id="1812631533912615985">Vabasta vahelehed</translation> <translation id="1813278315230285598">Teenused</translation> <translation id="18139523105317219">EDI-osapoole nimi</translation> <translation id="1815083418640426271">Kleebi lihttekstina</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chrome'i juhib automatiseeritud testtarkvara.</translation> <translation id="2070909990982335904">Punktiga algavad nimed on reserveeritud süsteemile. Valige teine nimi.</translation> <translation id="2071393345806050157">Kohalikku logifaili pole.</translation> -<translation id="2074527029802029717">Vabasta vaheleht</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% akut</translation> <translation id="2075959085554270910">Võimaldab lubada/keelata funktsioonid Koputa klõpsamiseks ja Puudutusega lohistamine</translation> <translation id="2076269580855484719">Peida pistikprogramm</translation> @@ -1352,7 +1343,6 @@ <translation id="3045447014237878114">See sait laadis automaatselt alla mitu faili</translation> <translation id="3046910703532196514">Veebileht, valmis</translation> <translation id="304747341537320566">Kõnesünteesimootorid</translation> -<translation id="304826556400666995">Vahekaartide summutuse tühistamine</translation> <translation id="3053013834507634016">Sertifikaadi võtme kasutus</translation> <translation id="3057861065630527966">Fotode ja videote varundamine</translation> <translation id="3060379269883947824">Luba funktsioon Vali ja kuula</translation> @@ -1965,7 +1955,7 @@ <translation id="3979748722126423326">Luba <ph name="NETWORKDEVICE" /></translation> <translation id="3981760180856053153">Sisestati vale salvestamistüüp.</translation> <translation id="3982375475032951137">Seadistage brauser vaid mõne lihtsa sammuga</translation> -<translation id="3983400541576569538">Osade rakenduste andmed võivad kaotsi minna</translation> +<translation id="3983400541576569538">Mõnede rakenduste andmed võivad kaotsi minna</translation> <translation id="3983586614702900908">tundmatu müüja seadmed</translation> <translation id="3984159763196946143">Demorežiimi ei saanud käivitada</translation> <translation id="3987348946546879621">Andmemahtu säästeti</translation> @@ -2335,7 +2325,6 @@ <translation id="4628762811416793313">Linuxi konteineri seadistus ei jõudnud lõpule. Proovige uuesti.</translation> <translation id="4628948037717959914">Foto</translation> <translation id="4631887759990505102">Esitaja</translation> -<translation id="4632483769545853758">Tühista vahekaardi summutus</translation> <translation id="4633003931260532286">Laiendus nõuab üksust „<ph name="IMPORT_NAME" />” minimaalse versiooniga „<ph name="IMPORT_VERSION" />”, kuid installitud on ainult versioon „<ph name="INSTALLED_VERSION" />”</translation> <translation id="4634771451598206121">Logi uuesti sisse ...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> ei ole külaliskasutajatele saadaval.</translation> @@ -2399,7 +2388,6 @@ <translation id="4735803855089279419">Süsteemil ei õnnestunud määrata sellele seadmele seadme tuvastajaid.</translation> <translation id="4737715515457435632">Looge ühendus võrguga</translation> <translation id="473775607612524610">Värskenda</translation> -<translation id="474217410105706308">Summuta vahekaart</translation> <translation id="4742746985488890273">Riiulile kinnitamine</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Vaadake, kuidas rakendusi värskendada<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Sõnumid</translation> @@ -2624,7 +2612,6 @@ <translation id="5094721898978802975">Side koostööd tegevate omarakendustega</translation> <translation id="5097002363526479830">Võrguga „<ph name="NAME" />” ühenduse loomine ebaõnnestus: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Ava kõik järjehoidjad</translation> -<translation id="5105855035535475848">Kinnita vahelehed</translation> <translation id="5108967062857032718">Seaded – Androidi rakenduste eemaldamine</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">&Järjehoidjate haldur</translation> @@ -2689,7 +2676,6 @@ <translation id="520621735928254154">Viga sertifikaadi importimisel</translation> <translation id="5209320130288484488">Seadmeid ei leitud</translation> <translation id="5209518306177824490">SHA-1 sõrmejälg</translation> -<translation id="5210365745912300556">Sule vaheleht</translation> <translation id="5213481667492808996">Võrgu „<ph name="NAME" />” andmesideteenus on kasutamiseks valmis</translation> <translation id="5213891612754844763">Kuva puhverserveri seaded</translation> <translation id="521582610500777512">Fotost loobuti</translation> @@ -2740,7 +2726,6 @@ <translation id="5270167208902136840">Kuva veel <ph name="NUMBER_OF_MORE_APPS" /> rakendust</translation> <translation id="5275352920323889391">Koer</translation> <translation id="5275973617553375938">Google Drive'ist taastatud failid</translation> -<translation id="527605719918376753">Summuta vahekaart</translation> <translation id="527605982717517565">Luba alati JavaScript saidil <ph name="HOST" /></translation> <translation id="5280426389926346830">Kas soovite luua otsetee?</translation> <translation id="528208740344463258">Androidi rakenduste allalaadimiseks ja kasutamiseks peate esmalt installima selle kohustusliku värskenduse. Seadme <ph name="DEVICE_TYPE" /> värskendamise ajal ei saa te seda kasutada. <ph name="DEVICE_TYPE" /> taaskäivitatakse pärast installimise lõpulejõudmist.</translation> @@ -2863,7 +2848,6 @@ <translation id="5449551289610225147">Vale parool</translation> <translation id="5449588825071916739">Kõikide vahelehtede järjehoidjatesse lisamine</translation> <translation id="5449716055534515760">Sule &aken</translation> -<translation id="5453029940327926427">Sule vahelehed</translation> <translation id="5454166040603940656">teenusepakkujaga <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Kehtetu</translation> <translation id="5457459357461771897">Arvutis olevate fotode, muusika ja muu meedia lugemine ja kustutamine</translation> @@ -3328,7 +3312,6 @@ <translation id="6122875415561139701">Kirjutamistoiming pole seadmes „<ph name="DEVICE_NAME" />” lubatud.</translation> <translation id="6124650939968185064">Sellest laiendusest sõltuvad järgmised laiendused:</translation> <translation id="6125479973208104919">Kahjuks peate oma konto seadmesse <ph name="DEVICE_TYPE" /> uuesti lisama.</translation> -<translation id="612596694132302162">Tühista saidi vaigistus</translation> <translation id="6129691635767514872">Valitud andmed eemaldati Chrome'ist ja sünkroonitud seadmetest. Aadressil <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> võib teie Google'i kontol olla muus vormis sirvimisajalugu, nt otsingud ja muudes Google'i teenustes toimunud tegevused.</translation> <translation id="6129938384427316298">Netscape'i sertifikaadi kommentaar</translation> <translation id="6129953537138746214">Tühik</translation> @@ -3531,7 +3514,6 @@ <translation id="6436164536244065364">Kuva veebipoes</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – heli esitatakse</translation> <translation id="6442187272350399447">Vägev!</translation> -<translation id="6442697326824312960">Vahelehe vabastamine</translation> <translation id="6444070574980481588">Kuupäeva ja kellaaja määramine</translation> <translation id="6445450263907939268">Kui need on soovimatud muudatused, saate taastada eelmised seaded.</translation> <translation id="6447842834002726250">Küpsised</translation> @@ -3734,7 +3716,6 @@ <translation id="6770664076092644100">Kinnitamine NFC kaudu</translation> <translation id="6771503742377376720">On sertifitseerimisorgan</translation> <translation id="6777817260680419853">Ümbersuunamine blokeeriti</translation> -<translation id="6778959797435875428">Tühista saitide vaigistus</translation> <translation id="677965093459947883">Väga väike</translation> <translation id="6780439250949340171">hallata muid seadeid</translation> <translation id="6781284683813954823">Doodle'i vigurlogo link</translation> @@ -4051,7 +4032,6 @@ <translation id="7257666756905341374">Kopeeritud ja kleebitud andmete lugemine</translation> <translation id="7258697411818564379">PIN-kood on lisatud</translation> <translation id="7262004276116528033">Sisselogimisteenust hostib <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Sule vahelehed</translation> <translation id="7268659760406822741">Saadaolevad teenused</translation> <translation id="7270858098575133036">Küsi, kui sait tahab kasutada MIDI-seadmetele juurdepääsu saamiseks süsteemi eksklusiivseid sõnumeid</translation> <translation id="7272674038937250585">Kirjeldust ei ole sisestatud</translation> @@ -4241,7 +4221,6 @@ <translation id="7576032389798113292">6 x 4</translation> <translation id="7576690715254076113">Eksemplarhaaval</translation> <translation id="7576976045740938453">Ilmnes demorežiimi kontoga seotud probleem.</translation> -<translation id="7579149537961810247">Vaigista saidid</translation> <translation id="7580671184200851182">Esita sama heli kõigist kõlaritest (monoheli)</translation> <translation id="7581462281756524039">Puhastustööriist</translation> <translation id="7582582252461552277">Eelista seda võrku</translation> @@ -4595,7 +4574,6 @@ <translation id="8068253693380742035">Puudutage sisselogimiseks</translation> <translation id="8069615408251337349">Google'i pilvprintimine</translation> <translation id="8071432093239591881">Prindi kujutisena</translation> -<translation id="8072988827236813198">Kinnita vahelehed</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Rakenduse andmed võivad olla mis tahes andmed, mille rakendus on salvestanud (arendaja seadete põhjal), sh andmed, nagu kontaktid, sõnumid ja fotod.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Varundatud andmeid ei loeta teie lapse Drive'i salvestuskvoodi hulka.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Selle teenuse saate menüüs Seaded välja lülitada.<ph name="END_PARAGRAPH3" /></translation> @@ -4782,7 +4760,6 @@ <translation id="8368859634510605990">&Ava kõik järjehoidjad</translation> <translation id="8371695176452482769">Alustage rääkimist</translation> <translation id="8372369524088641025">Halb WEP-võti</translation> -<translation id="8373553483208508744">Summuta vahekaardid</translation> <translation id="8378714024927312812">Haldab teie organisatsioon</translation> <translation id="8379878387931047019">See seade ei toeta seda tüüpi turvavõtit, mida see veebisait nõuab</translation> <translation id="8382913212082956454">Kopeeri &e-posti aadress</translation> @@ -4890,7 +4867,6 @@ <translation id="8546930481464505581">Puuteriba kohandamine</translation> <translation id="8547013269961688403">Luba täisekraani luup</translation> <translation id="85486688517848470">Ülemise rea klahvide toimingu vahetamiseks hoidke all otsinguklahvi</translation> -<translation id="855081842937141170">Kinnita vaheleht</translation> <translation id="8551388862522347954">Litsentsid</translation> <translation id="8553342806078037065">Teiste inimeste haldamine</translation> <translation id="8554899698005018844">Keel puudub</translation> @@ -5204,7 +5180,6 @@ <translation id="9038430547971207796">Järgmisel korral avab seadme <ph name="DEVICE_TYPE" /> teie telefon. Funktsiooni Smart Lock saate välja lülitada menüüs Seaded.</translation> <translation id="9038649477754266430">Kasuta lehtede kiiremaks laadimiseks ennustusteenust</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Vahekaartide summutamine</translation> <translation id="9040661932550800571">Kas värskendada saidi <ph name="ORIGIN" /> parooli?</translation> <translation id="9041692268811217999">Administraator keelas juurdepääsu arvutis olevatele kohalikele failidele</translation> <translation id="9042893549633094279">Privaatsus ja turvalisus</translation> @@ -5302,7 +5277,6 @@ <translation id="920045321358709304">Otsi teenusest <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Ekraaniluku valikud</translation> <translation id="9203398526606335860">&Profileerimine lubatud</translation> -<translation id="9203478404496196495">Tühista vahekaardi summutus</translation> <translation id="9203904171912129171">Valige seade</translation> <translation id="9203962528777363226">Selle seadme administraator on keelanud uute kasutajate lisamise</translation> <translation id="9213073329713032541">Installimise alustamine õnnestus.</translation>
diff --git a/chrome/app/resources/generated_resources_fa.xtb b/chrome/app/resources/generated_resources_fa.xtb index 5e43d94..f70f6810 100644 --- a/chrome/app/resources/generated_resources_fa.xtb +++ b/chrome/app/resources/generated_resources_fa.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">برای رد شدن، ESCAPE را فشار دهید (فقط ساختهای غیررسمی).</translation> <translation id="1093457606523402488">شبکههای قابل مشاهده:</translation> <translation id="1094607894174825014">عملیات خواندن یا نوشتن با فاصله نامعتبری در این دستگاه درخواست شد: «<ph name="DEVICE_NAME" />».</translation> -<translation id="109758035718544977">باصدا کردن سایتها</translation> <translation id="1097658378307015415">قبل از ورود به سیستم، لطفاً جهت فعال کردن شبکه <ph name="NETWORK_ID" />، بهعنوان مهمان وارد شوید</translation> <translation id="1103523840287552314"><ph name="LANGUAGE" /> همیشه ترجمه شود</translation> <translation id="1108600514891325577">&توقف</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">با پنجره ناشناس، بدون ذخیره کردن سابقه مرور از وب استفاده کنید</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> اثرانگشت تنظیم شده است</translation> <translation id="1215411991991485844">برنامه جدید پسزمینه اضافه شد</translation> -<translation id="1216654534877302979">بیصدا کردن سایتها</translation> <translation id="1216659994753476700">متأسفیم. ما نمیتوانیم به نمایه شما دسترسی پیدا کنیم. فایلها و دادههای ذخیره شده در این دستگاه ممکن است از بین رفته باشند.<ph name="BR" /> <ph name="BR" /> باید نمایهتان را دوباره راهاندازی کنید.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">ذخیره کردن دادهها در حساب Google Drive شما</translation> <translation id="1288037062697528143">«نور شب» هنگام غروب آفتاب بهطور خودکار روشن میشود</translation> <translation id="1288300545283011870">مشخصات گفتار</translation> -<translation id="1293177648337752319">باصدا کردن سایت</translation> <translation id="1293264513303784526">دستگاه USB-C (درگاه سمت چپ)</translation> <translation id="1293556467332435079">فایلها</translation> <translation id="1296497012903089238">نوع گواهینامه</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">صفحه اصلی، صفحه برگه جدید است</translation> <translation id="1436671784520050284">ادامه راهاندازی</translation> <translation id="1436784010935106834">حذف شد</translation> -<translation id="1438632560381091872">وصل کردن صدای برگهها</translation> <translation id="1442392616396121389">پیشوند مسیریابی</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> انتخاب شد</translation> <translation id="1444628761356461360">این تنظیم توسط مالک دستگاه مدیریت میشود، <ph name="OWNER_EMAIL" />.</translation> @@ -385,7 +381,6 @@ <translation id="1567387640189251553">بعد از آخرین باری که گذرواژهتان را وارد کردید، صفحهکلید دیگری متصل شده است. ممکن است تلاش کند ضربهکلیدهای شما را به سرقت ببرد.</translation> <translation id="1567750922576943685">تأیید هویت به محافظت از اطلاعات شخصیتان کمک میکند</translation> <translation id="1567993339577891801">کنسول جاوا اسکریپت</translation> -<translation id="1568067597247500137">بیصدا کردن سایت</translation> <translation id="1568323446248056064">باز کردن تنظیمات نمایشگر دستگاه</translation> <translation id="1572266655485775982">فعال کردن Wi-Fi</translation> <translation id="1572585716423026576">تنظیم بهعنوان تصویر زمینه</translation> @@ -437,7 +432,6 @@ <translation id="1643072738649235303">امضای X9.62 ECDSA با SHA-1</translation> <translation id="1644574205037202324">سابقه</translation> <translation id="1645516838734033527">برای ایمن نگهداشتن <ph name="DEVICE_TYPE" />، Smart Lock در تلفنتان قفل صفحه لازم دارد.</translation> -<translation id="1646102270785326155">اگر کاربر حذف شود، همه فایلها و دادههای محلی مربوط به او برای همیشه حذف خواهند شد. $1 همچنان میتواند بعداً به سیستم وارد شود.</translation> <translation id="1646982517418478057">برای رمزگذاری این گواهی، گذرواژهای وارد کنید</translation> <translation id="164814987133974965">کاربر نظارت شده میتواند وب را با راهنمایی شما کاوش کند. شما به عنوان مدیر کاربر نظارت شده میتوانید وبسایتهای خاصی را <ph name="BEGIN_BOLD" />مجاز یا ممنوع کنید<ph name="END_BOLD" />، @@ -496,7 +490,6 @@ <translation id="1729533290416704613">این برنامه صفحهای را که هنگام جستجو از Omnibox نشان داده میشود، کنترل میکند.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />برای حذف برنامهها به «تنظیمات > فروشگاه Google Play > مدیریت اولویتهای Android > برنامهها یا مدیر برنامه» بروید. سپس روی برنامهای که میخواهید حذف نصب شود ضربه بزنید (ممکن است برای پیدا کردن برنامه نیاز باشد صفحه را تند به راست یا چپ بکشید). سپس روی «حذف نصب» یا «غیرفعال کردن» ضربه بزنید.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">در حال ارسال درخواست...</translation> -<translation id="1732215134274276513">برداشتن پین برگهها</translation> <translation id="1733383495376208985">رمزگذاری دادههای همگامسازیشده با <ph name="BEGIN_LINK" />عبارت عبور همگامسازی<ph name="END_LINK" /> خودتان. این کار شامل روشهای پرداخت و نشانیهای موجود در Google Pay نمیشود.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> ممکن است نتواند خود را بهروز نگه دارد</translation> <translation id="1736419249208073774">کاوش</translation> @@ -548,7 +541,6 @@ <translation id="1807938677607439181">همه فایلها</translation> <translation id="1809734401532861917">نشانکها، سابقه، گذرواژهها و سایر تنظیماتم به <ph name="USER_EMAIL_ADDRESS" /> اضافه شود</translation> <translation id="1810764548349082891">پیشنمایشی وجود ندارد</translation> -<translation id="1812631533912615985">برگههای لغو پین</translation> <translation id="1813278315230285598">سرویسها</translation> <translation id="18139523105317219">نام طرف EDI</translation> <translation id="1815083418640426271">جایگذاری بهعنوان نوشتار ساده</translation> @@ -707,7 +699,6 @@ <translation id="2065405795449409761">Chrome توسط نرمافزار آزمایش خودکاری کنترل میشود.</translation> <translation id="2070909990982335904">نامهایی که با نقطه شروع میشوند برای سیستم رزرو شدهند. لطفاً" نام دیگری انتخاب کنید.</translation> <translation id="2071393345806050157">فایل گزارش محلی وجود ندارد.</translation> -<translation id="2074527029802029717">باز کردن برگه</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />٪ باتری</translation> <translation id="2075959085554270910">به شما امکان میدهد «کلیک با یک ضربه» و «کشیدن با ضربه زدن» را فعال/غیرفعال کنید</translation> <translation id="2076269580855484719">پنهان کردن این افزایه</translation> @@ -1353,7 +1344,6 @@ <translation id="3045447014237878114">این سایت چند فایل را بهطور خودکار بارگیری کرد</translation> <translation id="3046910703532196514">صفحهٔ وب، کامل</translation> <translation id="304747341537320566">موتورهای گفتار</translation> -<translation id="304826556400666995">وصل کردن صدای برگهها</translation> <translation id="3053013834507634016">کاربرد کلید گواهی</translation> <translation id="3057861065630527966">از عکسها و ویدئوهایتان پشتیبان بگیرید</translation> <translation id="3060379269883947824">فعال کردن «انتخاب برای شنیدن»</translation> @@ -2339,7 +2329,6 @@ <translation id="4628762811416793313">راهاندازی محتوی Linux تکمیل نشد. لطفاً دوباره امتحان کنید.</translation> <translation id="4628948037717959914">عکس</translation> <translation id="4631887759990505102">هنرمند</translation> -<translation id="4632483769545853758">وصل کردن صدای برگه</translation> <translation id="4633003931260532286">افزونه به «<ph name="IMPORT_NAME" />» با نسخه حداقل «<ph name="IMPORT_VERSION" />» نیاز دارد اما تنها نسخه «<ph name="INSTALLED_VERSION" />» نصب شده است</translation> <translation id="4634771451598206121">ورود مجدد به سیستم...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> برای کاربران مهمان دردسترس نیست.</translation> @@ -2404,7 +2393,6 @@ <translation id="4736292055110123391">همگامسازی نشانکها، سابقه، و موارد دیگر در همه دستگاهها</translation> <translation id="4737715515457435632">لطفاً به شبکه وصل شوید.</translation> <translation id="473775607612524610">بهروزرسانی</translation> -<translation id="474217410105706308">بیصدا کردن برگه</translation> <translation id="4742746985488890273">پین به راهانداز</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />با نحوه بهروزرسانی برنامهها آشنا شوید<ph name="END_LINK" /></translation> <translation id="4746351372139058112">پیامها</translation> @@ -2629,7 +2617,6 @@ <translation id="5094721898978802975">ارتباط با برنامههای بومی همکار</translation> <translation id="5097002363526479830">اتصال ناموفق به شبکه "<ph name="NAME" />":<ph name="DETAILS" /></translation> <translation id="5101042277149003567">باز کردن همه نشانکها</translation> -<translation id="5105855035535475848">پین کردن برگهها</translation> <translation id="5108967062857032718">تنظیمات - حذف برنامههای Android</translation> <translation id="5109044022078737958">ورزشکار</translation> <translation id="5111692334209731439">مدیر &نشانک</translation> @@ -2694,7 +2681,6 @@ <translation id="520621735928254154">خطا در وارد کردن گواهی</translation> <translation id="5209320130288484488">دستگاهی یافت نشد</translation> <translation id="5209518306177824490">اثر انگشت SHA-1</translation> -<translation id="5210365745912300556">بستن برگه</translation> <translation id="5213481667492808996">سرویس داده «<ph name="NAME" />» شما آماده استفاده است</translation> <translation id="5213891612754844763">نمایش تنظیمات پروکسی</translation> <translation id="521582610500777512">عکس صرف نظر شد</translation> @@ -2746,7 +2732,6 @@ <translation id="5272654297705279635">تنظیمات سفارشی</translation> <translation id="5275352920323889391">سگ</translation> <translation id="5275973617553375938">فایلهای بازیابیشده از Google Drive</translation> -<translation id="527605719918376753">بیصدا کردن برگه</translation> <translation id="527605982717517565">همیشه جاوا اسکریپت در <ph name="HOST" /> مجاز باشد</translation> <translation id="5280426389926346830">میانبر ایجاد شود؟</translation> <translation id="528208740344463258">برای بارگیری و استفاده از برنامههای Android، ابتدا باید این بهروزرسانی الزامی را نصب کنید. وقتی <ph name="DEVICE_TYPE" /> شما درحال بهروزرسانی است، نمیتوانید از آن استفاده کنید. پس از تکمیل نصب، <ph name="DEVICE_TYPE" /> بازراهاندازی میشود.</translation> @@ -2869,7 +2854,6 @@ <translation id="5449551289610225147">گذرواژه نامعتبر است</translation> <translation id="5449588825071916739">نشانکگذاری همه برگهها...</translation> <translation id="5449716055534515760">بستن &پنجره</translation> -<translation id="5453029940327926427">بستن برگهها</translation> <translation id="5454166040603940656">با <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">نامعتبر</translation> <translation id="5457459357461771897">خواندن و حذف عکسها، موسیقی، و سایر رسانهها از رایانهتان</translation> @@ -3334,7 +3318,6 @@ <translation id="6122875415561139701">عملیات نوشتن در این دستگاه مجاز نیست: «<ph name="DEVICE_NAME" />».</translation> <translation id="6124650939968185064">افزودنههای زیر به این برنامه افزودنی وابسته هستند:</translation> <translation id="6125479973208104919">متأسفانه دوباره باید حسابتان را به این <ph name="DEVICE_TYPE" /> اضافه کنید.</translation> -<translation id="612596694132302162">باصدا کردن سایت</translation> <translation id="6129691635767514872">دادههای انتخابشده از Chrome و دستگاههای همگامسازیشده برداشته شدهاند. ممکن است حساب Google شما در <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> شکلهای دیگری از سابقه مرور (مانند جستجوها و فعالیت از سایر سرویسهای Google) داشته باشد.</translation> <translation id="6129938384427316298">نظر گواهی Netscape</translation> <translation id="6129953537138746214">فاصله</translation> @@ -3537,7 +3520,6 @@ <translation id="6436164536244065364">نمایش در فروشگاه وب</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - پخش خودکار</translation> <translation id="6442187272350399447">معرکه</translation> -<translation id="6442697326824312960">باز کردن برگه</translation> <translation id="6444070574980481588">تنظیم تاریخ و زمان</translation> <translation id="6445450263907939268">اگر این تغییرات مدنظر شما نبود، میتوانید تنظیمات قبلیتان را بازیابی کنید.</translation> <translation id="6447842834002726250">کوکیها</translation> @@ -3740,7 +3722,6 @@ <translation id="6770664076092644100">بهتأیید رساندن ازطریق NFC</translation> <translation id="6771503742377376720">یک ارائه دهنده مجوز است</translation> <translation id="6777817260680419853">هدایت کردن مسدود شده است</translation> -<translation id="6778959797435875428">باصدا کردن سایتها</translation> <translation id="677965093459947883">خیلی کوچک</translation> <translation id="6780439250949340171">مدیریت سایر تنظیمات</translation> <translation id="6781284683813954823">پیوند Doodle</translation> @@ -4057,7 +4038,6 @@ <translation id="7257666756905341374">خواندن دادههایی که کپی و جایگذاری میکنید</translation> <translation id="7258697411818564379">پین اضافه شد</translation> <translation id="7262004276116528033">این خدمات ورود به سیستم توسط <ph name="SAML_DOMAIN" /> میزبانی شده است</translation> -<translation id="7268365133021434339">بستن برگهها</translation> <translation id="7268659760406822741">خدمات موجود</translation> <translation id="7270858098575133036">اگر سایتی میخواهد از پیامهای انحصاری سیستم برای دسترسی به دستگاههای MIDI استفاده کند سؤال شود</translation> <translation id="7272674038937250585">توضیحی ارائه نشده است</translation> @@ -4247,7 +4227,6 @@ <translation id="7576032389798113292">۶x۴</translation> <translation id="7576690715254076113">تلفیق کردن</translation> <translation id="7576976045740938453">در رابطه با حساب حالت نمایشی، مشکلی پیش آمد.</translation> -<translation id="7579149537961810247">بیصدا کردن سایتها</translation> <translation id="7580671184200851182">یک صدا را از طریق همه بلندگوها پخش کنید (تک صوتی)</translation> <translation id="7581462281756524039">یک ابزار پاکسازی</translation> <translation id="7582582252461552277">این شبکه ارجحیت دارد</translation> @@ -4601,7 +4580,6 @@ <translation id="8068253693380742035">برای ورود به سیستم لمس کنید</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">چاپ کردن بهعنوان تصویر</translation> -<translation id="8072988827236813198">پین کردن برگهها</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />دادههای برنامه میتوانند هر دادهای باشند که برنامه (براساس تنظیمات برنامهنویس) ذخیره کرده است، ازجمله دادههایی مانند مخاطبین، پیامها و عکسها.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />دادههای پشتیبانگیریشده جزو سهمیه فضای ذخیرهسازی Drive فرزندتان حساب نمیشوند.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />میتوانید این سرویس را در «تنظیمات» خاموش کنید.<ph name="END_PARAGRAPH3" /></translation> @@ -4787,7 +4765,6 @@ <translation id="8368859634510605990">&باز کردن همه نشانکها</translation> <translation id="8371695176452482769">اکنون صحبت کنید</translation> <translation id="8372369524088641025">کلید WEP نادرست</translation> -<translation id="8373553483208508744">بیصدا کردن برگهها</translation> <translation id="8378714024927312812">توسط سازمانتان مدیریت میشود</translation> <translation id="8379878387931047019">این دستگاه نوع کلید امنیتیِ درخواستی ازجانب این وبسایت را پشتیبانی نمیکند</translation> <translation id="8382913212082956454">کپی آدرس &ایمیل</translation> @@ -4895,7 +4872,6 @@ <translation id="8546930481464505581">سفارشی کردن «نوار لمسی»</translation> <translation id="8547013269961688403">فعال کردن ذرهبین تمامصفحه</translation> <translation id="85486688517848470">برای جابهجایی بین رفتار کلیدهای ردیف بالا، کلید جستجو را نگهدارید</translation> -<translation id="855081842937141170">پین کردن برگه</translation> <translation id="8551388862522347954">مجوزها</translation> <translation id="8553342806078037065">مدیریت افراد دیگر</translation> <translation id="8554899698005018844">زبانی موجود نیست</translation> @@ -5210,7 +5186,6 @@ <translation id="9038430547971207796">دفعه بعد، تلفنتان قفل <ph name="DEVICE_TYPE" /> را باز میکند. در «تنظیمات»، Smart Lock را خاموش کنید.</translation> <translation id="9038649477754266430">استفاده از یک سرویس پیشبینی برای بار کردن سریعتر صفحهها</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">بیصدا کردن برگهها</translation> <translation id="9040661932550800571">گذرواژه <ph name="ORIGIN" /> بهروزرسانی شود؟</translation> <translation id="9041692268811217999">دسترسی به فایلهای محلی موجود در دستگاهتان، توسط سرپرست شما غیرفعال شده است</translation> <translation id="9042893549633094279">حریم خصوصی و امنیت</translation> @@ -5308,7 +5283,6 @@ <translation id="920045321358709304">جستجوی <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">گزینههای قفل صفحه</translation> <translation id="9203398526606335860">&نمایه سازی فعال شد</translation> -<translation id="9203478404496196495">وصل کردن صدای برگه</translation> <translation id="9203904171912129171">انتخاب دستگاه</translation> <translation id="9203962528777363226">سرپرست این دستگاه امکان افزوده شدن کاربران جدید را غیرفعال کرده است</translation> <translation id="9213073329713032541">نصب باموفقیت شروع شد.</translation>
diff --git a/chrome/app/resources/generated_resources_fi.xtb b/chrome/app/resources/generated_resources_fi.xtb index ce31a66..ddae1188 100644 --- a/chrome/app/resources/generated_resources_fi.xtb +++ b/chrome/app/resources/generated_resources_fi.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Ohita painamalla ESCAPE (vain epävirallisissa ohjelmistoversioissa).</translation> <translation id="1093457606523402488">Näkyvät verkot:</translation> <translation id="1094607894174825014">Lukemis- tai kirjoittamistoimintoa pyydettiin virheellisellä poikkeamalla laitteella <ph name="DEVICE_NAME" />.</translation> -<translation id="109758035718544977">Poista sivustojen mykistys</translation> <translation id="1097658378307015415">Aloita vierailijakäyttö ennen sisäänkirjautumista aktivoidaksesi verkon <ph name="NETWORK_ID" />.</translation> <translation id="1103523840287552314">Käännä <ph name="LANGUAGE" /> aina</translation> <translation id="1108600514891325577">Py&säytä</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Avaa incognito-ikkuna, jos haluat selata verkkoa ilman tietojen tallentumista selaushistoriaan.</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> sormenjälkeä määritetty</translation> <translation id="1215411991991485844">Uusi taustasovellus lisätty</translation> -<translation id="1216654534877302979">Mykistä sivustoja</translation> <translation id="1216659994753476700">Emme valitettavasti voi käyttää profiiliasi. Tälle laitteelle tallennetut tiedostot ja tiedot on voitu menettää.<ph name="BR" /> <ph name="BR" /> Sinun on asetettava profiilisi uudelleen.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Tallenna tiedot Google Drive -tiliin</translation> <translation id="1288037062697528143">Yövalo käynnistyy automaattisesti, kun aurinko laskee.</translation> <translation id="1288300545283011870">Puheominaisuudet</translation> -<translation id="1293177648337752319">Poista sivuston mykistys</translation> <translation id="1293264513303784526">C-tyypin USB-laite (vasemman sivun portti)</translation> <translation id="1293556467332435079">Tiedostot</translation> <translation id="1296497012903089238">Varmenteen tyyppi</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Etusivu on Uusi välilehti -sivu</translation> <translation id="1436671784520050284">Jatka määritystä</translation> <translation id="1436784010935106834">Poistettu</translation> -<translation id="1438632560381091872">Poista välilehtien mykistys</translation> <translation id="1442392616396121389">Reititysetuliite</translation> <translation id="144283815522798837">Valittu: <ph name="NUMBER_OF_ITEMS_SELECTED" /></translation> <translation id="1444628761356461360">Tätä asetusta hallinnoi laitteen omistaja <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Laitteeseen on kytketty eri näppäimistö sen jälkeen, kun annoit salasanasi edellisen kerran. Sillä voidaan yrittää kaapata näppäinpainalluksesi.</translation> <translation id="1567750922576943685">Henkilöllisyyden vahvistaminen auttaa suojaamaan henkilötietojasi</translation> <translation id="1567993339577891801">JavaScript-konsoli</translation> -<translation id="1568067597247500137">Mykistä sivusto</translation> <translation id="1568323446248056064">Avaa näytön laiteasetukset</translation> <translation id="1572266655485775982">Wi-Fi käyttöön</translation> <translation id="1572585716423026576">Aseta taustakuvaksi</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">X9.62 ECDSA ‑allekirjoitus, jossa on SHA-1</translation> <translation id="1644574205037202324">Historia</translation> <translation id="1645516838734033527">Jotta <ph name="DEVICE_TYPE" /> pysyy turvassa, Smart Lock edellyttää näytön lukitusta puhelimessa.</translation> -<translation id="1646102270785326155">Kun tämä käyttäjä poistetaan, kaikki käyttäjään liittyvät tiedostot ja paikalliset tiedot poistetaan pysyvästi. $1 voi edelleen kirjautua sisään.</translation> <translation id="1646982517418478057">Salaa tämä varmenne antamalla salasana.</translation> <translation id="164814987133974965">Valvottu käyttäjä voi selata verkkoa valvojan opastuksella. Valvotun käyttäjän hallinnoija voi <ph name="BEGIN_BOLD" />sallia tai estää<ph name="END_BOLD" /> tiettyjen sivustojen käytön, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Määrittää myös omnibox-hakujen aloitussivun.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Jos haluat poistaa sovelluksia, valitse Asetukset > Google Play Kauppa > Hallitse Android-asetuksia > Sovellukset tai Sovellusten hallinta. Valitse sitten sovellus, jonka haluat poistaa (jos sovellusta ei näy, pyyhkäise oikealle tai vasemmalle). Valitse sitten Poista tai Poista käytöstä.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Lähetetään pyyntöä...</translation> -<translation id="1732215134274276513">Irrota välilehdet</translation> <translation id="1733383495376208985">Salaa synkronoitu data omalla <ph name="BEGIN_LINK" />synkronoinnin tunnuslauseella<ph name="END_LINK" />. Tämä ei koske Google Payhin tallennettuja maksutapoja tai osoitteita.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> ei välttämättä pysty päivittymään automaattisesti.</translation> <translation id="1736419249208073774">Tutustu</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Kaikki tiedostot</translation> <translation id="1809734401532861917">Lisää kirjanmerkit, salasanat ja muut asetukset tilille <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Esikatselu ei saatavilla</translation> -<translation id="1812631533912615985">Irrota välilehdet</translation> <translation id="1813278315230285598">Palvelut</translation> <translation id="18139523105317219">EDI-osapuolen nimi</translation> <translation id="1815083418640426271">Liitä tekstinä</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Automaattinen testausohjelmisto hallinnoi Chromea.</translation> <translation id="2070909990982335904">Pisteellä alkavat nimet on varattu järjestelmän käyttöön. Valitse toinen nimi.</translation> <translation id="2071393345806050157">Paikallista lokitiedostoa ei ole.</translation> -<translation id="2074527029802029717">Irrota välilehti</translation> <translation id="2075474481720804517">Akku: <ph name="BATTERY_PERCENTAGE" /> %</translation> <translation id="2075959085554270910">Voit ottaa napauttamalla klikkaamisen ja vetämisen käyttöön tai poistaa sen käytöstä.</translation> <translation id="2076269580855484719">Piilota tämä laajennus</translation> @@ -1353,7 +1344,6 @@ <translation id="3045447014237878114">Tämä sivusto latasi useita tiedostoja automaattisesti</translation> <translation id="3046910703532196514">Verkkosivu, täydellinen</translation> <translation id="304747341537320566">Puhemoottorit</translation> -<translation id="304826556400666995">Poista välilehtien mykistys</translation> <translation id="3053013834507634016">Varmenteen avaimen käyttö</translation> <translation id="3057861065630527966">Varmuuskopioi valokuvasi ja videosi.</translation> <translation id="3060379269883947824">Ota käyttöön Teksti puhuttuna</translation> @@ -2333,7 +2323,6 @@ <translation id="4628762811416793313">Linux-säilön määritys ei onnistunut. Yritä uudelleen.</translation> <translation id="4628948037717959914">Valokuva</translation> <translation id="4631887759990505102">Esittäjä</translation> -<translation id="4632483769545853758">Poista välilehden mykistys</translation> <translation id="4633003931260532286">Laajennus edellyttää sovellusliittymän <ph name="IMPORT_NAME" /> vähimmäisversiota <ph name="IMPORT_VERSION" />, mutta asennettuna on vain versio <ph name="INSTALLED_VERSION" />.</translation> <translation id="4634771451598206121">Kirjaudu uudelleen sisään...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> ei ole vieraskäyttäjien saatavilla.</translation> @@ -2397,7 +2386,6 @@ <translation id="4735803855089279419">Järjestelmä ei onnistunut määrittämään tämän laitteen laitetunnisteita.</translation> <translation id="4737715515457435632">Muodosta verkkoyhteys</translation> <translation id="473775607612524610">Päivitä</translation> -<translation id="474217410105706308">Mykistä välilehti</translation> <translation id="4742746985488890273">Kiinnitä hyllyyn</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Katso, miten sovelluksia päivitetään<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Viestit</translation> @@ -2622,7 +2610,6 @@ <translation id="5094721898978802975">Kommunikoida yhteistyötä tekevien natiivisovellusten kanssa</translation> <translation id="5097002363526479830">Yhteyden muodostaminen verkkoon "<ph name="NAME" />" epäonnistui: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Avaa kaikki kirjanmerkit</translation> -<translation id="5105855035535475848">Kiinnitä välilehdet</translation> <translation id="5108967062857032718">Asetukset – Poista Android-sovellukset</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">&Kirjanmerkkien hallinta</translation> @@ -2687,7 +2674,6 @@ <translation id="520621735928254154">Varmenteen tuontivirhe</translation> <translation id="5209320130288484488">Laitteita ei löytynyt</translation> <translation id="5209518306177824490">SHA-1-tunnistetiedosto</translation> -<translation id="5210365745912300556">Sulje välilehti</translation> <translation id="5213481667492808996">Datapalvelu (<ph name="NAME" />) on valmiina käyttöön</translation> <translation id="5213891612754844763">Näytä välityspalvelinasetukset</translation> <translation id="521582610500777512">Kuva hylättiin</translation> @@ -2738,7 +2724,6 @@ <translation id="5270167208902136840">Näytä <ph name="NUMBER_OF_MORE_APPS" /> muuta sovellusta</translation> <translation id="5275352920323889391">Koira</translation> <translation id="5275973617553375938">Google Drivesta palautetut tiedostot</translation> -<translation id="527605719918376753">Mykistä välilehti</translation> <translation id="527605982717517565">Salli aina JavaScript sivustossa <ph name="HOST" /></translation> <translation id="5280426389926346830">Luodaanko pikakuvake?</translation> <translation id="528208740344463258">Tämä pakollinen päivitys täytyy asentaa, ennen kuin voit ladata ja käyttää Android-sovelluksia. <ph name="DEVICE_TYPE" /> ei ole käytettävissä päivityksen aikana. <ph name="DEVICE_TYPE" /> käynnistetään uudelleen asennuksen jälkeen.</translation> @@ -2861,7 +2846,6 @@ <translation id="5449551289610225147">Virheellinen salasana</translation> <translation id="5449588825071916739">Lisää kaikki välilehdet kirjanmerkkeihin</translation> <translation id="5449716055534515760">&Sulje ikkuna</translation> -<translation id="5453029940327926427">Sulje välilehdet</translation> <translation id="5454166040603940656">palvelulla <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Virheellinen</translation> <translation id="5457459357461771897">Käyttää ja poistaa valokuvia, musiikkia ja muuta tietokoneesi mediaa</translation> @@ -3326,7 +3310,6 @@ <translation id="6122875415561139701">Kirjoitustoiminto ei ole sallittu laitteella <ph name="DEVICE_NAME" />.</translation> <translation id="6124650939968185064">Seuraavat laajennukset ovat riippuvaisia tästä laajennuksesta:</translation> <translation id="6125479973208104919">Sinun on lisättävä tilisi laitteelle <ph name="DEVICE_TYPE" /> uudelleen.</translation> -<translation id="612596694132302162">Poista sivuston mykistys</translation> <translation id="6129691635767514872">Valitut tiedot on poistettu Chromesta ja synkronoiduilta laitteilta. Google-tililläsi voi olla muita selaushistoriatietoja, esimerkiksi hakuja ja toimintaa muista Google-palveluista, osoitteessa <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Netscape-varmenteen kommentti</translation> <translation id="6129953537138746214">Välilyönti</translation> @@ -3531,7 +3514,6 @@ <translation id="6436164536244065364">Näytä Web Storessa</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – toistaa ääntä</translation> <translation id="6442187272350399447">Hymiöinen</translation> -<translation id="6442697326824312960">Irrota välilehti</translation> <translation id="6444070574980481588">Aseta päivämäärä ja aika</translation> <translation id="6445450263907939268">Jos et pidä muutoksista, voit palauttaa aiemmat asetuksesi.</translation> <translation id="6447842834002726250">Evästeet</translation> @@ -3734,7 +3716,6 @@ <translation id="6770664076092644100">Vahvista NFC:n kautta</translation> <translation id="6771503742377376720">On varmenteen myöntäjä</translation> <translation id="6777817260680419853">Uudelleenohjaus estetty</translation> -<translation id="6778959797435875428">Poista sivustojen mykistys</translation> <translation id="677965093459947883">Hyvin pieni</translation> <translation id="6780439250949340171">hallinnoi muita asetuksia</translation> <translation id="6781284683813954823">Doodle-linkki</translation> @@ -4051,7 +4032,6 @@ <translation id="7257666756905341374">Lukea kopioimiasi ja liittämiäsi tietoja</translation> <translation id="7258697411818564379">PIN-koodi on lisätty</translation> <translation id="7262004276116528033">Tätä kirjautumispalvelua ylläpitää <ph name="SAML_DOMAIN" />.</translation> -<translation id="7268365133021434339">Sulje välilehdet</translation> <translation id="7268659760406822741">Käytettävissä olevat palvelut</translation> <translation id="7270858098575133036">Kysy, kun sivusto haluaa käyttää MIDI-laitteita järjestelmän omien viestien avulla</translation> <translation id="7272674038937250585">Ei kuvausta</translation> @@ -4241,7 +4221,6 @@ <translation id="7576032389798113292">6 x 4</translation> <translation id="7576690715254076113">Kokoa</translation> <translation id="7576976045740938453">Esittelytilan tilin kanssa tapahtui ongelma.</translation> -<translation id="7579149537961810247">Mykistä sivustoja</translation> <translation id="7580671184200851182">Toista äänet samanlaisina kaikista kaiuttimista (monotoisto)</translation> <translation id="7581462281756524039">Poistotyökalu</translation> <translation id="7582582252461552277">Käytä tätä verkkoa</translation> @@ -4594,7 +4573,6 @@ <translation id="8068253693380742035">Kirjaudu sisään koskettamalla</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Tulosta kuvana</translation> -<translation id="8072988827236813198">Kiinnitä välilehdet</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Sovellustiedot voivat olla mitä tahansa tietoja, joita sovellus on tallentanut (kehittäjän asetusten perusteella), mukaan lukien yhteystietoja, viestejä ja valokuvia.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Varmuuskopioidut tiedot eivät kuluta lapsesi tallennustilaa Drivessa.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Voit poistaa tämän palvelun käytöstä asetuksissa.<ph name="END_PARAGRAPH3" /></translation> @@ -4780,7 +4758,6 @@ <translation id="8368859634510605990">Avaa kaikki kirjanmerkit</translation> <translation id="8371695176452482769">Puhu nyt</translation> <translation id="8372369524088641025">Väärä WEP-avain</translation> -<translation id="8373553483208508744">Mykistä välilehdet</translation> <translation id="8378714024927312812">Organisaatiosi ylläpitämä</translation> <translation id="8379878387931047019">Tämä laite ei tue tämän sivuston pyytämää suojausavaintyyppiä</translation> <translation id="8382913212082956454">Kopioi s&ähköpostiosoite</translation> @@ -4888,7 +4865,6 @@ <translation id="8546930481464505581">Muokkaa kosketuspalkkia</translation> <translation id="8547013269961688403">Ota koko näytön suurennus käyttöön</translation> <translation id="85486688517848470">Pidä hakunäppäintä pohjassa, jos haluat vaihtaa ylärivin näppäinten toimintaa.</translation> -<translation id="855081842937141170">Kiinnitä välilehti</translation> <translation id="8551388862522347954">Käyttöoikeudet</translation> <translation id="8553342806078037065">Hallitse muita henkilöitä</translation> <translation id="8554899698005018844">Ei kieltä</translation> @@ -5202,7 +5178,6 @@ <translation id="9038430547971207796">Seuraavalla kerralla puhelimesi avaa laitteen <ph name="DEVICE_TYPE" /> lukituksen. Poista Smart Lock käytöstä Asetuksissa.</translation> <translation id="9038649477754266430">Ennakointipalvelun avulla voit ladata sivuja nopeammin</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Mykistä välilehdet</translation> <translation id="9040661932550800571">Päivitetäänkö salasana: <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Järjestelmänvalvojasi on estänyt sinua käyttämästä koneellesi tallennettuja tiedostoja.</translation> <translation id="9042893549633094279">Tietosuoja ja turvallisuus</translation> @@ -5300,7 +5275,6 @@ <translation id="920045321358709304">Hae hakukoneella <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Näytön lukitusvaihtoehdot</translation> <translation id="9203398526606335860">&Profilointi on käytössä</translation> -<translation id="9203478404496196495">Poista välilehden mykistys</translation> <translation id="9203904171912129171">Valitse laite</translation> <translation id="9203962528777363226">Tämän laitteen järjestelmänvalvoja on estänyt uusien käyttäjien lisäämisen</translation> <translation id="9213073329713032541">Asennus käynnistyi.</translation>
diff --git a/chrome/app/resources/generated_resources_fil.xtb b/chrome/app/resources/generated_resources_fil.xtb index f0c0171c..6d8d456 100644 --- a/chrome/app/resources/generated_resources_fil.xtb +++ b/chrome/app/resources/generated_resources_fil.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Pindutin ang ESCAPE upang lumaktaw (Mga hindi opisyal na build lamang).</translation> <translation id="1093457606523402488">Mga Nakikitang Network:</translation> <translation id="1094607894174825014">Ang read o write na operation ay hiniling nang may di-wastong offset sa: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">I-unmute ang Mga Site</translation> <translation id="1097658378307015415">Bago mag-sign in, mangyaring pumasok bilang Bisita upang i-activate ang network <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Palaging i-translate ang <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Huminto</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Gamitin ang web nang hindi nase-save ang iyong history ng pag-browse gamit ang isang incognito window</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> ang naka-set up na fingerprint</translation> <translation id="1215411991991485844">Nadagdag ang bagong background na app</translation> -<translation id="1216654534877302979">I-mute ang mga site</translation> <translation id="1216659994753476700">Paumanhin. Hindi namin ma-access ang iyong profile. Maaaring nawala na ang mga file at data na nakaimbak sa device na ito.<ph name="BR" /> <ph name="BR" /> Kakailanganin mong i-set up muli ang iyong profile.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Mag-imbak ng data sa iyong Google Drive account</translation> <translation id="1288037062697528143">Awtomatikong mag-o-on ang Night Light sa paglubog ng araw</translation> <translation id="1288300545283011870">Mga Property ng Pagsasalita</translation> -<translation id="1293177648337752319">I-unmute ang Site</translation> <translation id="1293264513303784526">USB-C device (port sa kaliwa)</translation> <translation id="1293556467332435079">Mga File</translation> <translation id="1296497012903089238">Uri ng Certificate</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Ang homepage ay ang pahina ng Bagong Tab</translation> <translation id="1436671784520050284">Ipagpatuloy ang pag-set up</translation> <translation id="1436784010935106834">Inalis</translation> -<translation id="1438632560381091872">Mag-unmute ng mga tab</translation> <translation id="1442392616396121389">Routing prefix</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> ang napili</translation> <translation id="1444628761356461360">Ang setting na ito ay pinamamahalaan ng may-ari ng device, <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Nagkonekta ng ibang keyboard mula nang huli mong inilagay ang iyong password. Maaaring sinusubukan nitong nakawin ang iyong mga keystroke.</translation> <translation id="1567750922576943685">Nakakatulong ang pag-verify sa iyong pagkakakilanlang maprotektahan ang personal na impormasyon mo</translation> <translation id="1567993339577891801">Console ng JavaScript</translation> -<translation id="1568067597247500137">I-mute ang site</translation> <translation id="1568323446248056064">Buksan ang mga setting ng display device</translation> <translation id="1572266655485775982">I-enable ang Wi-Fi</translation> <translation id="1572585716423026576">Itakda bilang wallpaper</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">X9.62 ECDSA Signature na may SHA-1</translation> <translation id="1644574205037202324">History</translation> <translation id="1645516838734033527">Upang panatilihing ligtas ang iyong <ph name="DEVICE_TYPE" />, kinakailangan ng Smart Lock ng lock ng screen sa telepono mo.</translation> -<translation id="1646102270785326155">Kapag inalis na ang user na ito, permanenteng ide-delete ang lahat ng file at lokal na data na nauugnay sa kanya. Makakapag-sign in pa rin si $1 sa ibang pagkakataon.</translation> <translation id="1646982517418478057">Mangyaring maglagay ng password upang i-encrypt ang certificate na ito</translation> <translation id="164814987133974965">Ma-e-explore ng isang pinangangasiwaang user ang web sa iyong patnubay. Bilang tagapamahala ng isang pinangangasiwaang user, maaari mong <ph name="BEGIN_BOLD" />payagan o pagbawalan<ph name="END_BOLD" /> ang ilang partikular na website, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Kinokontrol din nito kung anong pahina ang ipinapakita kapag naghanap ka mula sa Omnibox.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Para mag-alis ng mga app, pumunta sa Mga Setting > Google Play Store > Pamahalaan ang mga kagustuhan sa Android > Mga App o Application manager. Pagkatapos ay i-tap ang app na gusto mong i-uninstall (maaaring kailanganin mong mag-swipe pakanan o pakaliwa para mahanap ang app). Pagkatapos, i-tap ang I-uninstall o I-disable.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Ipinapadala ang paghiling...</translation> -<translation id="1732215134274276513">I-unpin ang Mga Tab</translation> <translation id="1733383495376208985">I-encrypt ang naka-sync na data gamit ang iyong sariling <ph name="BEGIN_LINK" />passphrase sa pag-sync<ph name="END_LINK" />. Hindi kasama rito ang mga paraan ng pagbabayad at address mula sa Google Pay.</translation> <translation id="1734824808160898225">Maaaring hindi patuloy na ma-update ng <ph name="PRODUCT_NAME" /> ang sarili nito</translation> <translation id="1736419249208073774">I-explore</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Lahat ng file</translation> <translation id="1809734401532861917">Idagdag ang aking mga bookmark, history, mga password, at iba pang setting sa <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Walang available na preview</translation> -<translation id="1812631533912615985">I-unpin ang mga tab</translation> <translation id="1813278315230285598">Services</translation> <translation id="18139523105317219">EDI Party Name</translation> <translation id="1815083418640426271">I-paste Bilang Plain Text</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Kinokontrol ang Chrome ng naka-automate na pansubok na software.</translation> <translation id="2070909990982335904">Nakalaan para sa system ang mga pangalang nagsisimula sa tuldok. Mangyaring pumili ng isa pang pangalan.</translation> <translation id="2071393345806050157">Walang lokal na log file.</translation> -<translation id="2074527029802029717">I-unpin ang tab</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% Baterya</translation> <translation id="2075959085554270910">Nagbibigay-daan sa iyong i-enable/disable ang tap-to-click at pag-tap para mag-drag</translation> <translation id="2076269580855484719">Itago ang plugin na ito</translation> @@ -1352,7 +1343,6 @@ <translation id="3045447014237878114">Awtomatikong nag-download ng maraming file ang site na ito</translation> <translation id="3046910703532196514">Webpage, Kumpleto</translation> <translation id="304747341537320566">Mga Engine sa Pagsasalita</translation> -<translation id="304826556400666995">Mag-unmute ng Mga Tab</translation> <translation id="3053013834507634016">Paggamit ng Certificate Key </translation> <translation id="3057861065630527966">I-back up ang iyong mga larawan at video</translation> <translation id="3060379269883947824">I-enable ang Select to Speak</translation> @@ -2335,7 +2325,6 @@ <translation id="4628762811416793313">Hindi natapos ang pag-set up sa Linux container. Pakisubukang muli.</translation> <translation id="4628948037717959914">Larawan</translation> <translation id="4631887759990505102">Artist</translation> -<translation id="4632483769545853758">I-unmute ang Tab</translation> <translation id="4633003931260532286">Kinakailangan ng extension ang "<ph name="IMPORT_NAME" />" na may minimum na bersyon na "<ph name="IMPORT_VERSION" />," ngunit ang bersyon na "<ph name="INSTALLED_VERSION" />" lang ang naka-install</translation> <translation id="4634771451598206121">Muling mag-sign in...</translation> <translation id="4635398712689569051">Hindi available ang <ph name="PAGE_NAME" /> sa mga Bisitang user.</translation> @@ -2399,7 +2388,6 @@ <translation id="4735803855089279419">Hindi natukoy ng system ang mga pagkakakilanlan ng device para sa device na ito.</translation> <translation id="4737715515457435632">Mangyaring kumonekta sa isang network.</translation> <translation id="473775607612524610">I-update</translation> -<translation id="474217410105706308">I-mute ang Tab</translation> <translation id="4742746985488890273">I-pin sa Shelf</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Alamin kung paano i-update ang mga application<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Mga Mensahe</translation> @@ -2624,7 +2612,6 @@ <translation id="5094721898978802975">Makipag-ugnay sa mga nakikipagtulungang native na application</translation> <translation id="5097002363526479830">Nabigong kumonekta sa network na '<ph name="NAME" />': <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Buksan lahat ng mga bookmark</translation> -<translation id="5105855035535475848">I-pin ang mga tab</translation> <translation id="5108967062857032718">Mga Setting - Alisin ang mga Android app</translation> <translation id="5109044022078737958">Elma</translation> <translation id="5111692334209731439">&Bookmark Manager</translation> @@ -2689,7 +2676,6 @@ <translation id="520621735928254154">Error sa Pag-import ng Certificate</translation> <translation id="5209320130288484488">Walang nahanap na mga device</translation> <translation id="5209518306177824490">SHA-1 Fingerprint</translation> -<translation id="5210365745912300556">Isara ang tab</translation> <translation id="5213481667492808996">Magagamit na ang iyong serbisyo ng data ng '<ph name="NAME" />'</translation> <translation id="5213891612754844763">Ipakita ang mga setting ng proxy</translation> <translation id="521582610500777512">Na-discard ang larawan</translation> @@ -2740,7 +2726,6 @@ <translation id="5270167208902136840">Magpakita ng <ph name="NUMBER_OF_MORE_APPS" /> pang app</translation> <translation id="5275352920323889391">Aso</translation> <translation id="5275973617553375938">Mga nabawing file mula sa Google Drive</translation> -<translation id="527605719918376753">I-mute ang tab</translation> <translation id="527605982717517565">Palaging hayaan ang JavaScript sa <ph name="HOST" /></translation> <translation id="5280426389926346830">Gumawa ng Shortcut?</translation> <translation id="528208740344463258">Para mag-download at gumamit ng mga Android app, kailangan mo munang i-install ang kinakailangang update na ito. Habang nag-a-update ang iyong <ph name="DEVICE_TYPE" />, hindi mo ito magagamit. Kapag nakumpleto na ang pag-install, magre-restart ang iyong <ph name="DEVICE_TYPE" />.</translation> @@ -2863,7 +2848,6 @@ <translation id="5449551289610225147">Di-wastong password</translation> <translation id="5449588825071916739">I-bookmark ang Lahat ng Tab</translation> <translation id="5449716055534515760">Isara ang Win&dow</translation> -<translation id="5453029940327926427">Isara ang mga tab</translation> <translation id="5454166040603940656">sa <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Di-wasto</translation> <translation id="5457459357461771897">Basahin at i-delete ang mga larawan, musika at iba pang media sa iyong computer</translation> @@ -3328,7 +3312,6 @@ <translation id="6122875415561139701">Hindi pinapahintulutan ang write na operation sa: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">Nakadepende ang mga sumusunod na extension sa extension na ito:</translation> <translation id="6125479973208104919">Sa kasamaang-palad, kakailanganin mong idagdag muli ang iyong account sa <ph name="DEVICE_TYPE" /> na ito.</translation> -<translation id="612596694132302162">I-unmute ang site</translation> <translation id="6129691635767514872">Inalis sa Chrome at sa mga naka-sync na device ang napiling data. Maaaring may iba pang anyo ng history ng pag-browse ang iyong Google Account tulad ng mga paghahanap at aktibidad mula sa iba pang serbisyo ng Google sa <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Komento sa Netscape Certificate</translation> <translation id="6129953537138746214">Puwang</translation> @@ -3531,7 +3514,6 @@ <translation id="6436164536244065364">Tingnan sa Web Store</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - May tumutugtog na audio</translation> <translation id="6442187272350399447">Kahanga-hanga</translation> -<translation id="6442697326824312960">I-unpin ang Tab</translation> <translation id="6444070574980481588">Itakda ang petsa at oras</translation> <translation id="6445450263907939268">Kung hindi mo gusto ang mga pagbabagong ito, maaari mong ipanumbalik ang mga dati mong setting.</translation> <translation id="6447842834002726250">Cookies</translation> @@ -3734,7 +3716,6 @@ <translation id="6770664076092644100">I-verify sa pamamagitan ng NFC</translation> <translation id="6771503742377376720">Ay isang Certificate Authority</translation> <translation id="6777817260680419853">Na-block ang pag-redirect</translation> -<translation id="6778959797435875428">I-unmute ang mga site</translation> <translation id="677965093459947883">Napakaliit</translation> <translation id="6780439250949340171">pamahalaan ang ibang mga setting</translation> <translation id="6781284683813954823">Link ng Doodle</translation> @@ -4051,7 +4032,6 @@ <translation id="7257666756905341374">Basahin ang data na iyong kinokopya at pine-paste</translation> <translation id="7258697411818564379">Naidagdag ang iyong PIN</translation> <translation id="7262004276116528033">Hino-host ng <ph name="SAML_DOMAIN" /> ang serbisyo sa pag-sign in</translation> -<translation id="7268365133021434339">Isara ang Mga Tab</translation> <translation id="7268659760406822741">Mga available na serbisyo</translation> <translation id="7270858098575133036">Magtanong kapag gustong gumamit ng isang site ng mga eksklusibong mensahe ng system upang mag-access ng mga MIDI device</translation> <translation id="7272674038937250585">Walang ibinigay na paglalarawan</translation> @@ -4241,7 +4221,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">Tipunin</translation> <translation id="7576976045740938453">Nagkaproblema sa account ng demo mode.</translation> -<translation id="7579149537961810247">I-mute ang Mga Site</translation> <translation id="7580671184200851182">I-play ang parehong audio sa lahat ng speaker (mono audio)</translation> <translation id="7581462281756524039">Isang tool sa paglilinis</translation> <translation id="7582582252461552277">Gustuhin ang network na ito</translation> @@ -4595,7 +4574,6 @@ <translation id="8068253693380742035">Pindutin upang mag-sign in</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">I-print bilang larawan</translation> -<translation id="8072988827236813198">I-pin ang Mga Tab</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Ang data ng app ay maaaring anumang data na na-save ng app (batay sa mga setting ng developer), kabilang ang data gaya ng mga contact, mensahe, at larawan.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Hindi mabibilang sa quota sa storage ng Drive ng iyong anak ang data ng backup.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Maaari mong i-off ang serbisyong ito sa Mga Setting.<ph name="END_PARAGRAPH3" /></translation> @@ -4781,7 +4759,6 @@ <translation id="8368859634510605990">&Buksan ang lahat ng bookmark</translation> <translation id="8371695176452482769">Magsalita ngayon</translation> <translation id="8372369524088641025">Mahinang WEP key</translation> -<translation id="8373553483208508744">Mag-mute ng mga tab</translation> <translation id="8378714024927312812">Pinapamahalaan ng iyong organisasyon</translation> <translation id="8379878387931047019">Hindi sinusuportahan ng device na ito ang uri ng security key na hiniling ng website na ito</translation> <translation id="8382913212082956454">Kopyahin ang &email address</translation> @@ -4890,7 +4867,6 @@ <translation id="8546930481464505581">I-customize ang Touch Bar</translation> <translation id="8547013269961688403">I-enable ang fullscreen magnifier</translation> <translation id="85486688517848470">Pindutin nang matagal ang Key sa paghahanap upang palitan ang gawi ng mga key sa itaas na row</translation> -<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> @@ -5205,7 +5181,6 @@ <translation id="9038430547971207796">Sa susunod, iaa-unlock ng iyong telepono ang <ph name="DEVICE_TYPE" /> mo. I-off ang Smart Lock sa Mga Setting.</translation> <translation id="9038649477754266430">Gumamit ng serbisyo sa paghula upang ma-load ang mga page nang mas mabilis</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Mag-mute ng Mga Tab</translation> <translation id="9040661932550800571">I-update ang password para sa <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Na-disable ng iyong administrator ang access sa mga lokal na file sa iyong machine</translation> <translation id="9042893549633094279">Privacy at seguridad</translation> @@ -5303,7 +5278,6 @@ <translation id="920045321358709304">Maghanap sa <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Mga opsyon sa lock ng screen</translation> <translation id="9203398526606335860">&Pinagana ang pag-profile</translation> -<translation id="9203478404496196495">I-unmute ang tab</translation> <translation id="9203904171912129171">Pumili ng device</translation> <translation id="9203962528777363226">Hindi pinagana ng administrator ng device na ito ang pagdaragdag ng mga bagong user</translation> <translation id="9213073329713032541">Matagumpay na nasimulan ang pag-install.</translation>
diff --git a/chrome/app/resources/generated_resources_fr.xtb b/chrome/app/resources/generated_resources_fr.xtb index d54f17e4..5ac5683 100644 --- a/chrome/app/resources/generated_resources_fr.xtb +++ b/chrome/app/resources/generated_resources_fr.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Appuyez sur ECHAP pour ignorer (versions non officielles uniquement).</translation> <translation id="1093457606523402488">Réseaux visibles :</translation> <translation id="1094607894174825014">L'opération de lecture ou d'écriture a été demandée avec un décalage incorrect sur l'appareil <ph name="DEVICE_NAME" />.</translation> -<translation id="109758035718544977">Réactiver le son des sites</translation> <translation id="1097658378307015415">Avant de vous connecter, veuillez vous connecter en tant qu'invité afin d'activer le réseau <ph name="NETWORK_ID" />.</translation> <translation id="1103523840287552314">Toujours traduire les pages en <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Arrêter</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Parcourez le Web sans enregistrer votre historique de navigation à l'aide d'une fenêtre de navigation privée</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> empreintes digitales configurées</translation> <translation id="1215411991991485844">Nouvelle application en arrière-plan ajoutée</translation> -<translation id="1216654534877302979">Couper le son des sites</translation> <translation id="1216659994753476700">Impossible d'accéder à votre profil. Les fichiers et les données stockés sur cet appareil ont peut-être été perdus.<ph name="BR" /> <ph name="BR" /> Vous devrez configurer votre profil de nouveau.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Stocker les données dans votre compte Google Drive</translation> <translation id="1288037062697528143">L'éclairage nocturne sera activé automatiquement au coucher du soleil</translation> <translation id="1288300545283011870">Propriétés relatives à la voix</translation> -<translation id="1293177648337752319">Réactiver le son du site</translation> <translation id="1293264513303784526">Appareil USB de type C (port situé sur la gauche de l'appareil)</translation> <translation id="1293556467332435079">Fichiers</translation> <translation id="1296497012903089238">Type de certificat</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">La page Nouvel onglet est la page d'accueil.</translation> <translation id="1436671784520050284">Poursuivre la configuration</translation> <translation id="1436784010935106834">Supprimé</translation> -<translation id="1438632560381091872">Réactiver le son des onglets</translation> <translation id="1442392616396121389">Préfixe de routage</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> sélectionnés</translation> <translation id="1444628761356461360">Ce paramètre est géré par le propriétaire de l'appareil : <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Un clavier différent a été branché depuis la dernière fois où vous avez saisi votre mot de passe. Il est possible que ce soit pour enregistrer les touches sur lesquelles vous appuyez et vous soutirer ainsi des informations.</translation> <translation id="1567750922576943685">La validation de votre identité contribue à protéger vos informations personnelles</translation> <translation id="1567993339577891801">Console JavaScript</translation> -<translation id="1568067597247500137">Couper le son du site</translation> <translation id="1568323446248056064">Ouvrir les paramètres de l'écran</translation> <translation id="1572266655485775982">Activation du Wi-Fi</translation> <translation id="1572585716423026576">Définir comme fond d'écran</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">Signature X9.62 ECDSA avec SHA-1</translation> <translation id="1644574205037202324">Historique</translation> <translation id="1645516838734033527">Afin de protéger votre <ph name="DEVICE_TYPE" />, Smart Lock nécessite l'activation d'un verrouillage d'écran sur votre téléphone.</translation> -<translation id="1646102270785326155">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. $1 pourra toujours se connecter plus tard.</translation> <translation id="1646982517418478057">Veuillez saisir un mot de passe pour chiffrer ce certificat.</translation> <translation id="164814987133974965">Un utilisateur supervisé peut naviguer sur le Web avec votre aide. En tant que gestionnaire d'un tel utilisateur, vous pouvez : <ph name="BEGIN_BOLD" />autoriser ou interdire<ph name="END_BOLD" /> certains sites Web ; @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Elle contrôle également la page qui s'affiche lorsque vous effectuez une recherche dans l'omnibox.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Pour supprimer des applications, sélectionnez Paramètres > Google Play Store > Gérer les préférences Android > Applications ou Gestionnaire d'applications, puis appuyez sur l'application que vous souhaitez désinstaller. Vous devrez peut-être balayer l'écran vers la gauche ou la droite pour localiser l'application. Ensuite, appuyez sur "Désinstaller" ou "Désactiver".<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Envoi de la requête...</translation> -<translation id="1732215134274276513">Annuler l'épinglage des onglets</translation> <translation id="1733383495376208985">Chiffrer les données synchronisées avec votre propre <ph name="BEGIN_LINK" />phrase secrète de synchronisation<ph name="END_LINK" />. Ceci ne s'applique pas aux modes de paiement et adresses Google Pay.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> risque de ne pas rester à jour</translation> <translation id="1736419249208073774">Découvrir</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Tous les fichiers</translation> <translation id="1809734401532861917">Ajouter mes favoris, mon historique, mes mots de passe et d'autres paramètres au compte <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Aucun aperçu disponible</translation> -<translation id="1812631533912615985">Annuler l'épinglage des onglets</translation> <translation id="1813278315230285598">Services</translation> <translation id="18139523105317219">Nom de partie EDI</translation> <translation id="1815083418640426271">Coller en tant que texte brut</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chrome est contrôlé par un logiciel de test automatisé.</translation> <translation id="2070909990982335904">Les noms commençant par un point sont réservés au système. Veuillez sélectionner un autre nom.</translation> <translation id="2071393345806050157">Aucun fichier journal local.</translation> -<translation id="2074527029802029717">Retirer l'onglet</translation> <translation id="2075474481720804517">Niveau de la batterie : <ph name="BATTERY_PERCENTAGE" /> %</translation> <translation id="2075959085554270910">Permet d'activer ou de désactiver la fonctionnalité Taper pour cliquer et le déplacement tactile</translation> <translation id="2076269580855484719">Masquer ce plug-in</translation> @@ -1352,7 +1343,6 @@ <translation id="3045447014237878114">Plusieurs fichiers ont été téléchargés automatiquement via ce site</translation> <translation id="3046910703532196514">Page Web, complète</translation> <translation id="304747341537320566">Moteurs de synthèse vocale</translation> -<translation id="304826556400666995">Réactiver le son des onglets</translation> <translation id="3053013834507634016">Utilisation de la clé du certificat</translation> <translation id="3057861065630527966">Sauvegarder vos photos et vos vidéos</translation> <translation id="3060379269883947824">Activer "Sélectionner pour prononcer"</translation> @@ -2335,7 +2325,6 @@ <translation id="4628762811416793313">Impossible de configurer le conteneur Linux. Veuillez réessayer.</translation> <translation id="4628948037717959914">Photo</translation> <translation id="4631887759990505102">Artiste</translation> -<translation id="4632483769545853758">Réactiver le son de l'onglet</translation> <translation id="4633003931260532286">L'extension nécessite au minimum la version <ph name="IMPORT_VERSION" /> de <ph name="IMPORT_NAME" />, mais la version installée est la <ph name="INSTALLED_VERSION" /></translation> <translation id="4634771451598206121">Nouvelle connexion...</translation> <translation id="4635398712689569051">La page <ph name="PAGE_NAME" /> n'est pas accessible aux utilisateurs invités.</translation> @@ -2399,7 +2388,6 @@ <translation id="4735803855089279419">Impossible de déterminer les identifiants de cet appareil.</translation> <translation id="4737715515457435632">Veuillez vous connecter à un réseau</translation> <translation id="473775607612524610">Mettre à jour</translation> -<translation id="474217410105706308">Couper le son de l'onglet</translation> <translation id="4742746985488890273">Épingler sur l'étagère</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Découvrir comment mettre à jour des applications<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Messages</translation> @@ -2624,7 +2612,6 @@ <translation id="5094721898978802975">Communiquer avec les applications natives associées</translation> <translation id="5097002363526479830">Échec de la connexion au réseau "<ph name="NAME" />" : <ph name="DETAILS" />.</translation> <translation id="5101042277149003567">Ouvrir tous les favoris</translation> -<translation id="5105855035535475848">Épingler les onglets</translation> <translation id="5108967062857032718">Paramètres – Supprimer des applications Android</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">&Gestionnaire de favoris</translation> @@ -2689,7 +2676,6 @@ <translation id="520621735928254154">Erreur d'importation du certificat</translation> <translation id="5209320130288484488">Aucun appareil trouvé.</translation> <translation id="5209518306177824490">Empreinte SHA-1</translation> -<translation id="5210365745912300556">Fermer l'onglet</translation> <translation id="5213481667492808996">Votre service de données "<ph name="NAME" />" est disponible</translation> <translation id="5213891612754844763">Afficher les paramètres de proxy</translation> <translation id="521582610500777512">La photo a été supprimée.</translation> @@ -2740,7 +2726,6 @@ <translation id="5270167208902136840">Afficher <ph name="NUMBER_OF_MORE_APPS" /> autres applications</translation> <translation id="5275352920323889391">Chien</translation> <translation id="5275973617553375938">Fichiers récupérés sur Google Drive</translation> -<translation id="527605719918376753">Couper le son de l'onglet</translation> <translation id="527605982717517565">Toujours exécuter JavaScript sur <ph name="HOST" /></translation> <translation id="5280426389926346830">Créer un raccourci ?</translation> <translation id="528208740344463258">Pour télécharger et utiliser des applications Android, vous devez d'abord installer cette mise à jour obligatoire. Vous ne pouvez pas utiliser votre <ph name="DEVICE_TYPE" /> pendant la mise à jour. Une fois l'installation terminée, votre <ph name="DEVICE_TYPE" /> redémarrera.</translation> @@ -2863,7 +2848,6 @@ <translation id="5449551289610225147">Mot de passe incorrect</translation> <translation id="5449588825071916739">Ajouter tous les onglets aux favoris…</translation> <translation id="5449716055534515760">Fe&rmer la fenêtre</translation> -<translation id="5453029940327926427">Fermer les onglets</translation> <translation id="5454166040603940656">avec <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Non valide</translation> <translation id="5457459357461771897">Accéder aux photos, à la musique et aux autres fichiers multimédias stockés sur votre ordinateur et les supprimer</translation> @@ -3329,7 +3313,6 @@ <translation id="6122875415561139701">L'opération d'écriture n'est pas autorisée sur l'appareil <ph name="DEVICE_NAME" />.</translation> <translation id="6124650939968185064">Les extensions suivantes dépendent de cette extension :</translation> <translation id="6125479973208104919">Malheureusement, vous devrez ajouter à nouveau votre compte sur cet appareil <ph name="DEVICE_TYPE" />.</translation> -<translation id="612596694132302162">Réactiver le son du site</translation> <translation id="6129691635767514872">Les données sélectionnées ont été supprimées de Chrome et des appareils synchronisés. Votre compte Google conserve peut-être d'autres formes d'historique de navigation, comme vos recherches ou vos activités via d'autres services Google sur la page <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Commentaire du certificat Netscape</translation> <translation id="6129953537138746214">Espace</translation> @@ -3532,7 +3515,6 @@ <translation id="6436164536244065364">Afficher dans le Web Store</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – Lecture audio</translation> <translation id="6442187272350399447">Super</translation> -<translation id="6442697326824312960">Retirer l'onglet</translation> <translation id="6444070574980481588">Définir la date et l'heure</translation> <translation id="6445450263907939268">Si vous ne souhaitiez pas effectuer ces modifications, vous pouvez restaurer les paramètres précédents.</translation> <translation id="6447842834002726250">Cookies</translation> @@ -3735,7 +3717,6 @@ <translation id="6770664076092644100">Valider via NFC</translation> <translation id="6771503742377376720">Est une autorité de certification</translation> <translation id="6777817260680419853">Redirection bloquée</translation> -<translation id="6778959797435875428">Réactiver le son des sites</translation> <translation id="677965093459947883">Très petite</translation> <translation id="6780439250949340171">Gérer d'autres paramètres</translation> <translation id="6781284683813954823">Lien vers le doodle</translation> @@ -4052,7 +4033,6 @@ <translation id="7257666756905341374">Accéder aux données que vous copiez et collez</translation> <translation id="7258697411818564379">Votre code a bien été ajouté</translation> <translation id="7262004276116528033">Ce service de connexion est hébergé par <ph name="SAML_DOMAIN" />.</translation> -<translation id="7268365133021434339">Fermer les onglets</translation> <translation id="7268659760406822741">Services disponibles</translation> <translation id="7270858098575133036">Demander lorsqu'un site souhaite utiliser des messages spécifiques au système pour accéder aux appareils MIDI</translation> <translation id="7272674038937250585">Aucune description fournie</translation> @@ -4242,7 +4222,6 @@ <translation id="7576032389798113292">6 x 4</translation> <translation id="7576690715254076113">Assembler</translation> <translation id="7576976045740938453">Un problème est survenu avec le compte du mode de démonstration.</translation> -<translation id="7579149537961810247">Couper le son des sites</translation> <translation id="7580671184200851182">Lire le même contenu audio sur toutes les enceintes (son mono)</translation> <translation id="7581462281756524039">Un outil de nettoyage</translation> <translation id="7582582252461552277">Préférer ce réseau</translation> @@ -4596,7 +4575,6 @@ <translation id="8068253693380742035">Appuyez pour vous connecter</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Imprimer en tant qu'image</translation> -<translation id="8072988827236813198">Épingler les onglets</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Les données d'applications correspondent aux données de tous types enregistrées par des applications en fonction des paramètres définis par le développeur. Elles incluent potentiellement des données sensibles comme des contacts, des messages et des photos.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Les données sauvegardées ne sont pas prises en compte dans le calcul du quota de stockage Drive de votre enfant.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Vous pouvez désactiver ce service dans les paramètres.<ph name="END_PARAGRAPH3" /></translation> @@ -4782,7 +4760,6 @@ <translation id="8368859634510605990">&Ouvrir tous les favoris</translation> <translation id="8371695176452482769">Parlez maintenant.</translation> <translation id="8372369524088641025">Clé WEP incorrecte</translation> -<translation id="8373553483208508744">Couper le son des onglets</translation> <translation id="8378714024927312812">Géré par votre organisation</translation> <translation id="8379878387931047019">Cet appareil n'est pas compatible avec la clé de sécurité demandée par le site Web</translation> <translation id="8382913212082956454">Copi&er l'adresse e-mail</translation> @@ -4890,7 +4867,6 @@ <translation id="8546930481464505581">Personnaliser la Touch Bar</translation> <translation id="8547013269961688403">Activer la loupe plein écran</translation> <translation id="85486688517848470">Maintenir la touche de recherche enfoncée pour modifier la fonction des touches de la rangée supérieure</translation> -<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> @@ -5204,7 +5180,6 @@ <translation id="9038430547971207796">La prochaine fois, votre téléphone déverrouillera votre <ph name="DEVICE_TYPE" />. Désactivez Smart Lock dans les paramètres.</translation> <translation id="9038649477754266430">Utiliser un service de prédiction pour charger les pages plus rapidement</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Couper le son des onglets</translation> <translation id="9040661932550800571">Mettre à jour le mot de passe pour <ph name="ORIGIN" /> ?</translation> <translation id="9041692268811217999">Votre administrateur a désactivé l'accès aux fichiers locaux sur votre ordinateur</translation> <translation id="9042893549633094279">Confidentialité et sécurité</translation> @@ -5302,7 +5277,6 @@ <translation id="920045321358709304">Rechercher avec <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Options de verrouillage de l'écran</translation> <translation id="9203398526606335860">&Profilage activé</translation> -<translation id="9203478404496196495">Réactiver le son de l'onglet</translation> <translation id="9203904171912129171">Sélectionner un appareil</translation> <translation id="9203962528777363226">L'administrateur de cet appareil a désactivé la fonctionnalité d'ajout de nouveaux utilisateurs</translation> <translation id="9213073329713032541">Installation démarrée avec succès.</translation>
diff --git a/chrome/app/resources/generated_resources_gu.xtb b/chrome/app/resources/generated_resources_gu.xtb index 51903f3..37e2d4b7 100644 --- a/chrome/app/resources/generated_resources_gu.xtb +++ b/chrome/app/resources/generated_resources_gu.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">છોડવા માટે ESCAPE દબાવો (ફક્ત બિન-આધિકારીક બિલ્ડ).</translation> <translation id="1093457606523402488">દૃશ્યક્ષમ નેટવર્ક્સ:</translation> <translation id="1094607894174825014">આના પર અમાન્ય ઓફસેટ સાથે વાંચન અથવા લેખન ઓપરેશનની વિનંતી કરી હતી: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">સાઇટને અનમ્યૂટ કરો</translation> <translation id="1097658378307015415">સાઇન ઇન કરતા પહેલા, કૃપા કરીને નેટવર્ક <ph name="NETWORK_ID" /> ને સક્રિય કરવા માટે એક અતિથિ તરીકે દાખલ થાઓ</translation> <translation id="1103523840287552314"><ph name="LANGUAGE" /> નો હંમેશાં અનુવાદ કરો</translation> <translation id="1108600514891325577">&Stop</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">છુપી વિંડો વડે, તમારો બ્રાઉઝિંગ ઇતિહાસ સાચવ્યા વિના વેબનો ઉપયોગ કરો</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> ફિંગરપ્રિન્ટ સેટ અપ</translation> <translation id="1215411991991485844">નવી પૃષ્ઠભૂમિ ઍપ્લિકેશન ઉમેરી છે</translation> -<translation id="1216654534877302979">સાઇટને મ્યૂટ કરો</translation> <translation id="1216659994753476700">અમે દિલગીર છીએ. અમે તમારી પ્રોફાઇલ ઍક્સેસ કરી શકતાં નથી. આ ઉપકરણ પર સંગ્રહિત કરવામાં આવેલ ફાઇલો અને ડેટા ગુમ થઈ શકે છે.<ph name="BR" /> <ph name="BR" /> તમારે ફરીથી તમારી પ્રોફાઇલ સેટ કરવાની જરૂર પડશે.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">તમારા Google ડ્રાઇવ એકાઉન્ટમાં ડેટા સ્ટોર કરો</translation> <translation id="1288037062697528143">સૂર્યાસ્ત વખતે રાત્રિ પ્રકાશ આપમેળે ચાલુ થશે</translation> <translation id="1288300545283011870">વાણીના ઇનપુટ નિયંત્રણોનું વિવરણ</translation> -<translation id="1293177648337752319">સાઇટને અનમ્યૂટ કરો</translation> <translation id="1293264513303784526">USB-C ઉપકરણ (ડાબું પોર્ટ)</translation> <translation id="1293556467332435079">ફાઇલો</translation> <translation id="1296497012903089238">પ્રમાણપત્રનો પ્રકાર</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">હોમપેજ એ નવું ટેબ પૃષ્ઠ છે</translation> <translation id="1436671784520050284">સેટઅપ ચાલુ રાખો</translation> <translation id="1436784010935106834">દૂર કરેલું</translation> -<translation id="1438632560381091872">ટૅબ્સને અનમ્યૂટ કરો</translation> <translation id="1442392616396121389">રાઉટિંગ પ્રીફિક્સ</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> પસંદ કરી</translation> <translation id="1444628761356461360">આ સેટિંગ ઉપકરણ માલિક, <ph name="OWNER_EMAIL" /> દ્વારા સંચાલિત થાય છે.</translation> @@ -385,7 +381,6 @@ <translation id="1567387640189251553">તમે છેલ્લે પાસવર્ડ દાખલ કર્યો, ત્યાર પછી એક અલગ કીબોર્ડ કનેક્ટ કરવામાં આવ્યું છે. તે તમારા કીસ્ટ્રોકની ચોરી કરવાનો પ્રયાસ કરતું હોઈ શકે છે.</translation> <translation id="1567750922576943685">તમારી ઓળખની ચકાસણી કરવાથી તમારી વ્યક્તિગત માહિતીનું રક્ષણ કરવામાં સહાય મળી રહે છે</translation> <translation id="1567993339577891801">JavaScript કન્સોલ</translation> -<translation id="1568067597247500137">સાઇટને મ્યૂટ કરો</translation> <translation id="1568323446248056064">ડિસ્પ્લે ડિવાઇસ સેટિંગ ખોલો</translation> <translation id="1572266655485775982">વાઇ-ફાઇ ચાલુ</translation> <translation id="1572585716423026576">વૉલપેપર તરીકે સેટ કરો</translation> @@ -436,7 +431,6 @@ <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="1646982517418478057">આ પ્રમાણપત્રને એન્ક્રિપ્ટ કરવા માટે કૃપા કરીને પાસવર્ડ દાખલ કરો</translation> <translation id="164814987133974965">એક નિરીક્ષિણ વપરાશકર્તા તમારા માર્ગદર્શન હેઠળ વેબ પર શોધ કરી શકે છે. નિરીક્ષિણ વપરાશકર્તાના મેનેજર તરીકે, તમે અમુક વેબસાઇટને <ph name="BEGIN_BOLD" />મંજૂર અથવા પ્રતિબંધિત<ph name="END_BOLD" /> કરી શકો છો. @@ -495,7 +489,6 @@ <translation id="1729533290416704613">જ્યારે તમે ઑમ્નિબૉક્સ પરથી શોધ કરો ત્યારે કયું પૃષ્ઠ બતાવવામાં આવે તે તેનું પણ નિયંત્રણ કરે છે.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />ઍપ કાઢી નાખવા માટે, સેટિંગ > Google Play સ્ટોર > Android પસંદગીઓ મેનેજ કરો > ઍપ અથવા ઍપ્લિકેશન મેનેજર પર જાઓ. પછી તમે અનઇન્સ્ટૉલ કરવા માગો છો તે ઍપ પર ટૅપ કરો (ઍપ શોધવા માટે તમારે જમણે અથવા ડાબે સ્વાઇપ કરવું જરૂરી હોઈ શકે છે). પછી 'અનઇન્સ્ટૉલ કરો' અથવા 'બંધ કરો' પર ટૅપ કરો.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">વિનંતિ મોકલી રહ્યું છે...</translation> -<translation id="1732215134274276513">ટૅબ્સ અનપિન કરો</translation> <translation id="1733383495376208985">તમારા પોતાના <ph name="BEGIN_LINK" />સિંક પાસફ્રેઝ<ph name="END_LINK" /> વડે સિંક કરેલા ડેટાને એન્ક્રિપ્ટ કરો. આમાં Google Payની ચુકવણી પદ્ધતિઓ અને ઍડ્રેસ સામેલ હોતા નથી.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> પોતાને અપડેટ રાખી શકશે નહીં</translation> <translation id="1736419249208073774">શોધખોળ કરો</translation> @@ -547,7 +540,6 @@ <translation id="1807938677607439181">બધી ફાઇલો</translation> <translation id="1809734401532861917">મારા બુકમાર્ક, ઇતિહાસ, પાસવર્ડ અને અન્ય સેટિંગ્સને <ph name="USER_EMAIL_ADDRESS" /> માં ઉમેરો</translation> <translation id="1810764548349082891">કોઈ પ્રીવ્યૂ ઉપલબ્ધ નથી</translation> -<translation id="1812631533912615985">ટૅબ્સ અનપિન કરો</translation> <translation id="1813278315230285598">સેવાઓ</translation> <translation id="18139523105317219">EDI પાર્ટી નામ</translation> <translation id="1815083418640426271">સાદી ટેક્સ્ટ તરીકે પેસ્ટ કરો</translation> @@ -706,7 +698,6 @@ <translation id="2065405795449409761">Chrome, સ્વચલિત પરીક્ષણ સોફ્ટવેર દ્વારા નિયંત્રિત કરવામાં આવી રહ્યું છે.</translation> <translation id="2070909990982335904">ડૉટથી પ્રારંભ થતા નામો સિસ્ટમ માટે આરક્ષિત છે. કૃપા કરી બીજું નામ પસંદ કરો.</translation> <translation id="2071393345806050157">કોઇ સ્થાનિક લૉગ ફાઇલ નથી.</translation> -<translation id="2074527029802029717">ટૅબ અનપિન કરો</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% બૅટરી</translation> <translation id="2075959085554270910">તમને ક્લિક કરવા હલકું દબાવોને અને ટૅપ કરીને ખેંચોને ચાલુ/બંધ કરવાની મંજૂરી આપે છે</translation> <translation id="2076269580855484719">આ પ્લગિન છુપાવો </translation> @@ -1353,7 +1344,6 @@ <translation id="3045447014237878114">આ સાઇટે એકથી વધુ ફાઇલો આપમેળે ડાઉનલોડ કરી છે</translation> <translation id="3046910703532196514">વેબપેજ, પૂર્ણ</translation> <translation id="304747341537320566">વાણી એન્જિનો</translation> -<translation id="304826556400666995">ટૅબ્સને અનમ્યૂટ કરો</translation> <translation id="3053013834507634016">પ્રમાણપત્ર કી ઉપયોગ</translation> <translation id="3057861065630527966">તમારા ફોટો અને વિડિઓઝનો બેકઅપ લો</translation> <translation id="3060379269883947824">સાંભળવા માટે પસંદ કરોને ચાલુ કરો</translation> @@ -2339,7 +2329,6 @@ <translation id="4628762811416793313">Linux કન્ટેનર સેટઅપ પૂર્ણ થયું નથી. કૃપા કરીને ફરી પ્રયાસ કરો.</translation> <translation id="4628948037717959914">ફોટો</translation> <translation id="4631887759990505102">કલાકાર</translation> -<translation id="4632483769545853758">ટૅબને અનમ્યૂટ કરો</translation> <translation id="4633003931260532286">એક્સટેંશનને ન્યૂનતમ વર્ઝન "<ph name="IMPORT_VERSION" />" સાથે "<ph name="IMPORT_NAME" />"ની જરૂર પડે છે, પણ ફક્ત વર્ઝન "<ph name="INSTALLED_VERSION" />" જ ઇન્સ્ટૉલ કરેલું છે</translation> <translation id="4634771451598206121">ફરીથી સાઇન ઇન કરો....</translation> <translation id="4635398712689569051">અતિથિ વપરાશકર્તાઓ માટે <ph name="PAGE_NAME" /> ઉપલબ્ધ નથી.</translation> @@ -2404,7 +2393,6 @@ <translation id="4736292055110123391">તમારા બધા ડિવાઇસ પર તમારા બુકમાર્ક, પાસવર્ડ, ઇતિહાસ અને વધુ સિંક કરો</translation> <translation id="4737715515457435632">કૃપા કરીને નેટવર્કથી કનેક્ટ કરો</translation> <translation id="473775607612524610">અપડેટ કરો</translation> -<translation id="474217410105706308">ટૅબ મ્યૂટ કરો</translation> <translation id="4742746985488890273">શેલ્ફ પર પિન કરો</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />ઍપ્લિકેશનો કેવી રીતે અપલોડ કરવી તે જાણો<ph name="END_LINK" /></translation> <translation id="4746351372139058112">સંદેશા</translation> @@ -2629,7 +2617,6 @@ <translation id="5094721898978802975">સહયોગ કરતી મૂળ ઍપ્લિકેશન સાથે સંચાર કરો</translation> <translation id="5097002363526479830">નેટવર્ક '<ph name="NAME" />' થી કનેક્ટ કરવામાં નિષ્ફળ: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">બધા બુકમાર્ક ખોલો</translation> -<translation id="5105855035535475848">ટૅબ્સ પિન કરો</translation> <translation id="5108967062857032718">સેટિંગ્સ - Android ઍપ્લિકેશનો દૂર કરો</translation> <translation id="5109044022078737958">મિઆ</translation> <translation id="5111692334209731439">&બુકમાર્ક વ્યવસ્થાપક</translation> @@ -2694,7 +2681,6 @@ <translation id="520621735928254154">પ્રમાણપત્ર આયાત કરવામાં ભૂલ</translation> <translation id="5209320130288484488">કોઈ ઉપકરણો મળ્યાં નથી</translation> <translation id="5209518306177824490">SHA-1 ફિંગરપ્રિંટ</translation> -<translation id="5210365745912300556">ટૅબ બંધ કરો</translation> <translation id="5213481667492808996">તમારી '<ph name="NAME" />' ડેટા સેવા ઉપયોગમાં લેવા માટે તૈયાર છે</translation> <translation id="5213891612754844763">પ્રૉક્સી સેટિંગ બતાવો</translation> <translation id="521582610500777512">ફોટો નિકાળવામાં આવ્યો હતો</translation> @@ -2746,7 +2732,6 @@ <translation id="5272654297705279635">કસ્ટમ સેટિંગ</translation> <translation id="5275352920323889391">કૂતરું</translation> <translation id="5275973617553375938">Google ડ્રાઇવમાંથી પુનર્પ્રાપ્ત ફાઇલો</translation> -<translation id="527605719918376753">ટૅબ મ્યૂટ કરો</translation> <translation id="527605982717517565"><ph name="HOST" /> પર JavaScript ને હંમેશા મંજૂરી આપો </translation> <translation id="5280426389926346830">શૉર્ટકટ બનાવીએ?</translation> <translation id="528208740344463258">Android ઍપ ડાઉનલોડ કરીને તેનો ઉપયોગ કરવા માટે, તમારે પહેલાં આ આવશ્યક અપડેટ ઇન્સ્ટૉલ કરવી જરૂરી છે. જ્યારે તમારું <ph name="DEVICE_TYPE" /> અપડેટ થઈ રહ્યું હોય, ત્યારે તમે તેનો ઉપયોગ કરી શકશો નહીં. એકવાર ઇન્સ્ટૉલેશન પૂર્ણ થઈ જાય એટલે તમારું <ph name="DEVICE_TYPE" /> ફરી શરૂ થશે.</translation> @@ -2869,7 +2854,6 @@ <translation id="5449551289610225147">અમાન્ય પાસવર્ડ</translation> <translation id="5449588825071916739">તમામ ટૅબ્સ બુકમાર્ક કરો</translation> <translation id="5449716055534515760">Close Win&dow</translation> -<translation id="5453029940327926427">ટૅબ્સ બંધ કરો</translation> <translation id="5454166040603940656"><ph name="PROVIDER" /> સાથે</translation> <translation id="5457113250005438886">અમાન્ય</translation> <translation id="5457459357461771897">વાંચો અને તમારા કમ્પ્યુટરમાંથી ફોટો, મ્યુઝિક અને બીજું મીડિયા ડિલીટ કરો</translation> @@ -3335,7 +3319,6 @@ <translation id="6122875415561139701">આના પર લેખન ઓપરેશનને મંજૂરી નથી: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">નીચેના એક્સ્ટેન્શન્સ આ એક્સ્ટેન્શન પર નિર્ભર કરે છે:</translation> <translation id="6125479973208104919">કમનસીબે, તમને આ <ph name="DEVICE_TYPE" />માં તમારું એકાઉન્ટ ઉમેરવાની જરૂર પડશે.</translation> -<translation id="612596694132302162">સાઇટને અનમ્યૂટ કરો</translation> <translation id="6129691635767514872">પસંદ કરેલો ડેટા Chrome અને તમારા સિંક કરેલ ડિવાઇસમાંથી ડિલીટ કરવામાં આવ્યો છે. તમારા Google એકાઉન્ટમાં બ્રાઉઝિંગ ઇતિહાસના બીજા સ્વરૂપો જેમ કે શોધ અને બીજા Google સેવાઓ પરની પ્રવૃત્તિઓ <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> પર હોય શકે છે.</translation> <translation id="6129938384427316298">નેટસ્કેપ પ્રમાણપત્ર ટિપ્પણી</translation> <translation id="6129953537138746214">જગ્યા</translation> @@ -3538,7 +3521,6 @@ <translation id="6436164536244065364">વેબ સ્ટોરમાં જુઓ</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - ઑડિઓ ચલાવવું</translation> <translation id="6442187272350399447">અદ્ભુત</translation> -<translation id="6442697326824312960">ટૅબ અનપિન કરો</translation> <translation id="6444070574980481588">તારીખ અને સમય સેટ કરો</translation> <translation id="6445450263907939268">જો તમે આ ફેરફારો ઇચ્છતા ન હોય, તો તમે તમારા પાછલાં સેટિંગને પહેલાંના જેવું કરો.</translation> <translation id="6447842834002726250">કૂકીઝ</translation> @@ -3741,7 +3723,6 @@ <translation id="6770664076092644100">NFC મારફતે ચકાસો</translation> <translation id="6771503742377376720">એ એક પ્રમાણન અધિકારી છે</translation> <translation id="6777817260680419853">રીડાયરેક્ટ કરવાનું બ્લૉક કર્યું</translation> -<translation id="6778959797435875428">સાઇટને અનમ્યૂટ કરો</translation> <translation id="677965093459947883">ખૂબ નાનું</translation> <translation id="6780439250949340171">અન્ય સેટિંગ્સનું સંચાલન કરો</translation> <translation id="6781284683813954823">ડૂડલ લિંક</translation> @@ -4058,7 +4039,6 @@ <translation id="7257666756905341374">તમે કૉપિ અને પેસ્ટ કરો એ ડેટાને વાંચો</translation> <translation id="7258697411818564379">તમારો પિન ઉમેરવામાં આવ્યો છે</translation> <translation id="7262004276116528033">આ સાઇન-ઇન સેવા <ph name="SAML_DOMAIN" /> દ્વારા હોસ્ટ થયેલી છે.</translation> -<translation id="7268365133021434339">ટૅબ્સ બંધ કરો</translation> <translation id="7268659760406822741">ઉપલબ્ધ સેવાઓ</translation> <translation id="7270858098575133036">MIDI ઉપકરણોને ઍક્સેસ કરવા માટે જ્યારે સાઇટ, સિસ્ટમ વિશિષ્ટ સંદેશાનો ઉપયોગ કરવા માગે ત્યારે કહો</translation> <translation id="7272674038937250585">કોઈ વર્ણન આપેલ નથી</translation> @@ -4248,7 +4228,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">કૉલેટ</translation> <translation id="7576976045740938453">ડેમો મોડ એકાઉન્ટમાં ભૂલ આવી.</translation> -<translation id="7579149537961810247">સાઇટને મ્યૂટ કરો</translation> <translation id="7580671184200851182">તમામ સ્પીકર્સ મારફતે સમાન ઑડિઓ ચલાવો (મોનો ઑડિઓ)</translation> <translation id="7581462281756524039">સફાઈ સાધન</translation> <translation id="7582582252461552277">આ નેટવર્કને પસંદ કરો</translation> @@ -4594,7 +4573,6 @@ <translation id="8068253693380742035">સાઇન ઇન કરવા માટે ટચ કરો</translation> <translation id="8069615408251337349">Google ક્લાઉડ પ્રિન્ટ</translation> <translation id="8071432093239591881">ફોટો તરીકે પ્રિન્ટ</translation> -<translation id="8072988827236813198">ટૅબ્સ પિન કરો</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />ઍપ ડેટા એ સંપર્કો, સંદેશા અને ફોટા જેવા ડેટા સહિત, ઍપ દ્વારા (ડેવલપર સેટિંગના આધારે) સાચવવામાં આવેલ કોઈપણ ડેટા હોય શકે છે.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />બૅકઅપ ડેટાની ગણતરી તમારા બાળકના ડ્રાઇવ સ્ટોરેજના ક્વોટામાં નહીં થાય.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />તમે સેટિંગમાંથી આ સેવા બંધ કરી શકશો.<ph name="END_PARAGRAPH3" /></translation> @@ -4780,7 +4758,6 @@ <translation id="8368859634510605990">બધાં બુકમાર્ક્સ &ખોલો</translation> <translation id="8371695176452482769">હવે બોલો</translation> <translation id="8372369524088641025">ખરાબ WEP કી</translation> -<translation id="8373553483208508744">ટૅબ્સને મ્યૂટ કરો</translation> <translation id="8378714024927312812">તમારી સંસ્થા દ્વારા મેનેજ કરેલ</translation> <translation id="8379878387931047019">આ ઉપકરણ આ વેબસાઇટ દ્વારા વિનંતી કરાયેલ સુરક્ષા કોડના પ્રકારનું સમર્થન કરતું નથી</translation> <translation id="8382913212082956454">&ઇમેઇલ સરનામું કૉપિ કરો</translation> @@ -4888,7 +4865,6 @@ <translation id="8546930481464505581">ટચ બારને કસ્ટમાઇઝ કરો</translation> <translation id="8547013269961688403">પૂર્ણસ્ક્રીન મેગ્નિફાયર ચાલુ કરો</translation> <translation id="85486688517848470">ટોચની-પંક્તિ કીની વર્તણૂંક બદલવા માટે શોધ કી દબાવી રાખો</translation> -<translation id="855081842937141170">ટૅબ પિન કરો</translation> <translation id="8551388862522347954">લાઇસેંસીસ</translation> <translation id="8553342806078037065">અન્ય લોકોને સંચાલિત કરો</translation> <translation id="8554899698005018844">કોઈ ભાષા નથી</translation> @@ -5203,7 +5179,6 @@ <translation id="9038430547971207796">આગલી વખતે, તમારો ફોન તમારા <ph name="DEVICE_TYPE" />ને અનલૉક કરશે. સેટિંગ્સમાં Smart Lock બંધ કરો.</translation> <translation id="9038649477754266430">પૃષ્ઠોને વધુ ઝડપથી લોડ કરવા માટે પૂર્વાનુમાન સેવાનો ઉપયોગ કરો</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">ટૅબ્સને મ્યૂટ કરો</translation> <translation id="9040661932550800571"><ph name="ORIGIN" /> માટેનો પાસવર્ડ અપડેટ કરીએ?</translation> <translation id="9041692268811217999">તમારા વ્યવસ્થાપકે તમારા મશીન પરની સ્થાનિક ફાઇલોનો ઍક્સેસ બંધ કરેલ છે</translation> <translation id="9042893549633094279">ગોપનીયતા અને સુરક્ષા</translation> @@ -5301,7 +5276,6 @@ <translation id="920045321358709304"><ph name="SEARCH_ENGINE" />માં શોધો</translation> <translation id="9201220332032049474">સ્ક્રીન લૉકના વિકલ્પો</translation> <translation id="9203398526606335860">&પ્રોફાઇલિંગ સક્ષમ</translation> -<translation id="9203478404496196495">ટૅબને અનમ્યૂટ કરો</translation> <translation id="9203904171912129171">ઉપકરણ પસંદ કરો</translation> <translation id="9203962528777363226">આ ઉપકરણનાં વ્યવસ્થાપકે નવા વપરાશકર્તાઓને ઉમેરવાથી અક્ષમ કર્યા છે</translation> <translation id="9213073329713032541">ઇન્સ્ટૉલેશન સફળતાપૂર્વક શરૂ થયું.</translation>
diff --git a/chrome/app/resources/generated_resources_hi.xtb b/chrome/app/resources/generated_resources_hi.xtb index a9d00780..8cbb303 100644 --- a/chrome/app/resources/generated_resources_hi.xtb +++ b/chrome/app/resources/generated_resources_hi.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">छोड़ने के लिए ESCAPE दबाएं (केवल गैर-आधिकारिक बिल्ड).</translation> <translation id="1093457606523402488">दृश्यमान नेटवर्क:</translation> <translation id="1094607894174825014">पढ़ें या लिखें संचालन का अनुरोध किसी अमान्य ऑफ़सेट के साथ इस पर किया गया था: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">साइटें अनम्यूट करें</translation> <translation id="1097658378307015415">प्रवेश करने से पहले, कृपया <ph name="NETWORK_ID" /> नेटवर्क सक्रिय करने के लिए अतिथि के रूप में प्रविष्ट हों</translation> <translation id="1103523840287552314"><ph name="LANGUAGE" /> का हमेशा अनुवाद करें</translation> <translation id="1108600514891325577">&रोकें</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">गुप्त विंडो के ज़रिए अपना ब्राउज़िंग इतिहास सेव किए बगैर वेब का उपयोग करें</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> फ़िंगरप्रिंट को सेट अप किया गया</translation> <translation id="1215411991991485844">नया पृष्ठभूमि ऐप्स जोड़ा गया</translation> -<translation id="1216654534877302979">साइटें म्यूट करें</translation> <translation id="1216659994753476700">हम क्षमा चाहते हैं. हम आपकी प्रोफ़ाइल एक्सेस नहीं कर सकते. हो सकता है कि इस डिवाइस पर संग्रहित फ़ाइलें और डेटा खो गया हो.<ph name="BR" /> <ph name="BR" /> आपको अपनी प्रोफ़ाइल फिर से सेट करनी होगी.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">डेटा को अपने Google डिस्क खाते में संगृहीत करें</translation> <translation id="1288037062697528143">सूर्यास्त होने पर नाइट लाइट अपने आप चालू हो जाएगी</translation> <translation id="1288300545283011870">बोली के विवरण</translation> -<translation id="1293177648337752319">साइट अनम्यूट करें</translation> <translation id="1293264513303784526">USB-C डिवाइस (बायां पोर्ट)</translation> <translation id="1293556467332435079">फ़ाइल</translation> <translation id="1296497012903089238">प्रमाणपत्र प्रकार</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">मुख्यपेज, नया टैब पेज है</translation> <translation id="1436671784520050284">सेटअप जारी रखें</translation> <translation id="1436784010935106834">निकाला गया</translation> -<translation id="1438632560381091872">टैब अनम्यूट करें</translation> <translation id="1442392616396121389">रूटिंग का प्रारंभिक भाग</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> चयनित</translation> <translation id="1444628761356461360">यह सेटिंग डिवाइस मालिक, <ph name="OWNER_EMAIL" /> द्वारा प्रबंधित है.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">आपके पिछली बार डाले गए पासवर्ड के बाद से एक अलग कीबोर्ड कनेक्ट किया गया है. यह आपके कीस्ट्रोक चुराने की कोशिश कर सकता है.</translation> <translation id="1567750922576943685">अपनी पहचान की पुष्टि करने से आपको अपनी निजी जानकारी सुरक्षित रखने में मदद मिलती है</translation> <translation id="1567993339577891801">JavaScript पैनल</translation> -<translation id="1568067597247500137">साइट म्यूट करें</translation> <translation id="1568323446248056064">प्रदर्शन डिवाइस सेटिंग खोलें</translation> <translation id="1572266655485775982">वाई-फ़ाई सक्षम</translation> <translation id="1572585716423026576">वॉलपेपर के तौर पर सेट करें</translation> @@ -440,7 +435,6 @@ <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="1646982517418478057">कृपया इस प्रमाणपत्र को एन्क्रिप्ट करने के लिए पासवर्ड डालें</translation> <translation id="164814987133974965">'निगरानी में रखा गया उपयोगकर्ता' आपके दिशा-निर्देशों के साथ वेब के बारे में और ज़्यादा जानकारी हासिल कर सकता है. 'निगरानी में रखे गए उपयोगकर्ता' के प्रबंधक के रूप में, आप कुछ वेबसाइटों को <ph name="BEGIN_BOLD" />अनुमति दे सकते हैं या रोक लगा<ph name="END_BOLD" /> सकते हैं, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">इससे यह भी नियंत्रित होता है कि जब आप खोज वाली पट्टी से खोजते हैं तब कौन सा पेज दिखाया जाए.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />ऐप्लिकेशन हटाने के लिए, सेटिंग > Google Play स्टोर > Android प्राथमिकताएं प्रबंधित करें > ऐप्लिकेशन या ऐप्लिकेशन एडमिन पर जाएं. फिर उस ऐप्लिकेशन पर टैप करें जिसे आप अनइंस्टॉल करना चाहते हैं (ऐप्लिकेशन ढूंढने के लिए आपको दाएं या बाएं स्वाइप करना पड़ सकता है). फिर अनइंस्टॉल करें या बंद करें पर टैप करें.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">अनुरोध भेजा जा रहा है...</translation> -<translation id="1732215134274276513">टैब बड़ी करें</translation> <translation id="1733383495376208985">सिंक किए गए डेटा को <ph name="BEGIN_LINK" />अपने खुद के सिंक लंबे पासवर्ड<ph name="END_LINK" /> से सुरक्षित करें. इसमें Google Pay से भुगतान करने के तरीके और पते शामिल नहीं हैं.</translation> <translation id="1734824808160898225">हो सकता है कि <ph name="PRODUCT_NAME" /> खुद को अपडेट नहीं रख पाए</translation> <translation id="1736419249208073774">बेहतर जानें</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">सभी फ़ाइलें</translation> <translation id="1809734401532861917">मेरे बुकमार्क, इतिहास, पासवर्ड और अन्य सेटिंग को <ph name="USER_EMAIL_ADDRESS" /> में जोड़ें</translation> <translation id="1810764548349082891">कोई पूर्वावलोकन उपलब्ध नहीं है</translation> -<translation id="1812631533912615985">टैब बड़ी करें</translation> <translation id="1813278315230285598">सेवाएं</translation> <translation id="18139523105317219">EDI पार्टी नाम</translation> <translation id="1815083418640426271">सादे टेक्स्ट के रूप में चिपकाएं</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chrome को स्वचालित परीक्षण सॉफ़्टवेयर नियंत्रित करता है.</translation> <translation id="2070909990982335904">डॉट से प्रारंभ हो रहे नाम सिस्टम के लिए आरक्षित हैं. कृपया कोई अन्य नाम चुनें.</translation> <translation id="2071393345806050157">कोई स्थानीय लॉग फ़ाइल नहीं है.</translation> -<translation id="2074527029802029717">टैब बड़ी करें</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% बैटरी</translation> <translation id="2075959085554270910">आपको क्लिक-के-लिए-टैप और टैप करके खींचने की सुविधा को चालू/बंद करने देता है</translation> <translation id="2076269580855484719">यह प्लग इन छुपाएं</translation> @@ -1352,7 +1343,6 @@ <translation id="3045447014237878114">इस साइट ने कई फ़ाइलें अपने आप डाउनलोड की हैं</translation> <translation id="3046910703532196514">वेबपेज, पूर्ण</translation> <translation id="304747341537320566">बोली इंजन</translation> -<translation id="304826556400666995">टैब अनम्यूट करें</translation> <translation id="3053013834507634016">प्रमाणपत्र कुंजी उपयोग</translation> <translation id="3057861065630527966">अपनी फ़ोटो और वीडियो का बैक अप लें</translation> <translation id="3060379269883947824">चुनें और सुनें सुविधा चालू करें</translation> @@ -2334,7 +2324,6 @@ <translation id="4628762811416793313">Linux कंटेनर का सेटअप पूरा नहीं हुआ. कृपया फिर से कोशिश करें.</translation> <translation id="4628948037717959914">फ़ोटो</translation> <translation id="4631887759990505102">कलाकार</translation> -<translation id="4632483769545853758">टैब अनम्यूट करें</translation> <translation id="4633003931260532286">एक्सटेंशन के लिए "<ph name="IMPORT_NAME" />" को न्यूनतम "<ph name="IMPORT_VERSION" />" वर्शन का होना चाहिए, लेकिन केवल "<ph name="INSTALLED_VERSION" />" वर्शन ही इंस्टॉल किया गया है</translation> <translation id="4634771451598206121">फिर से साइन इन करें...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> मेहमान उपयोगकर्ताओं के लिए उपलब्ध नहीं है.</translation> @@ -2398,7 +2387,6 @@ <translation id="4735803855089279419">सिस्टम इस डिवाइस के लिए डिवाइस पहचानकर्ताओं को तय नहीं कर सका.</translation> <translation id="4737715515457435632">कृपया किसी नेटवर्क से कनेक्ट करें</translation> <translation id="473775607612524610">अपडेट करें</translation> -<translation id="474217410105706308">टैब म्यूट करें</translation> <translation id="4742746985488890273">अलमारी से पिन करें</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />ऐप्लिकेशन अपडेट करने का तरीका जानें<ph name="END_LINK" /></translation> <translation id="4746351372139058112">संदेश</translation> @@ -2623,7 +2611,6 @@ <translation id="5094721898978802975">स्थानीय ऐप्स के साथ सहयोग करते हुए संचार करें</translation> <translation id="5097002363526479830">नेटवर्क से कनेक्ट करने में विफल '<ph name="NAME" />': <ph name="DETAILS" /></translation> <translation id="5101042277149003567">सभी बुकमार्क खोलें</translation> -<translation id="5105855035535475848">टैब छोटा करें</translation> <translation id="5108967062857032718">सेटिंग - Android ऐप्लिकेशन निकालें</translation> <translation id="5109044022078737958">मिया</translation> <translation id="5111692334209731439">&बुकमार्क प्रबंधक</translation> @@ -2688,7 +2675,6 @@ <translation id="520621735928254154">प्रमाणपत्र आयात करने में गड़बड़ी</translation> <translation id="5209320130288484488">कोई डिवाइस नहीं मिला</translation> <translation id="5209518306177824490">SHA-1 फ़िंगरप्रिंट</translation> -<translation id="5210365745912300556">टैब बंद करें</translation> <translation id="5213481667492808996">आपकी '<ph name="NAME" />' डेटा सेवा इस्तेमाल किए जाने के लिए तैयार है</translation> <translation id="5213891612754844763">प्रॉक्सी सेटिंग दिखाएं</translation> <translation id="521582610500777512">फ़ोटो को छोड़ दिया गया था</translation> @@ -2739,7 +2725,6 @@ <translation id="5270167208902136840"><ph name="NUMBER_OF_MORE_APPS" /> और ऐप्लिकेशन दिखाएं</translation> <translation id="5275352920323889391">श्वान</translation> <translation id="5275973617553375938">Google डिस्क से पुनर्प्राप्त की गई फ़ाइलें</translation> -<translation id="527605719918376753">टैब म्यूट करें</translation> <translation id="527605982717517565"><ph name="HOST" /> पर JavaScript को हमेशा अनुमति दें</translation> <translation id="5280426389926346830">शॉर्टकट बनाएं?</translation> <translation id="528208740344463258">Android ऐप्लिकेशन डाउनलोड करने और उनका इस्तेमाल करने के लिए, आपको सबसे पहले यह ज़रूरी अपडेट इंस्टॉल करना होगा. जब आपका <ph name="DEVICE_TYPE" /> अपडेट हो रहा हो, तो आप इसका इस्तेमाल नहीं कर सकते हैं. इंस्टॉल करने का काम पूरा हो जाने के बाद, आपका <ph name="DEVICE_TYPE" /> रीस्टार्ट हो जाएगा.</translation> @@ -2862,7 +2847,6 @@ <translation id="5449551289610225147">गलत पासवर्ड</translation> <translation id="5449588825071916739">सभी टैब बुकमार्क करें</translation> <translation id="5449716055534515760">विं&डो बंद करें</translation> -<translation id="5453029940327926427">टैब बंद करें</translation> <translation id="5454166040603940656"><ph name="PROVIDER" /> के साथ</translation> <translation id="5457113250005438886">अमान्य</translation> <translation id="5457459357461771897">अपने कंप्यूटर से फ़ोटो, संगीत और अन्य मीडिया पढ़ें और हटाएं</translation> @@ -3327,7 +3311,6 @@ <translation id="6122875415561139701">लिखें कार्रवाई की इस पर अनुमति नहीं है: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">निम्न एक्सटेंशन इस एक्सटेंशन पर निर्भर हैं:</translation> <translation id="6125479973208104919">दुर्भाग्यवश, आपको इस <ph name="DEVICE_TYPE" /> में अपना खाता फिर से जोड़ना होगा.</translation> -<translation id="612596694132302162">साइट अनम्यूट करें</translation> <translation id="6129691635767514872">चुना गया डेटा Chrome और सिंक किए गए सभी डिवाइस से हटा दिया गया है. हो सकता है कि आपके Google खाते में खोजों और <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> पर अन्य Google सेवाओं की गतिविधि जैसे अन्य प्रकार के ब्राउज़िंग इतिहास मौजूद हों.</translation> <translation id="6129938384427316298">Netscape प्रमाणपत्र टिप्पणी</translation> <translation id="6129953537138746214">Space</translation> @@ -3530,7 +3513,6 @@ <translation id="6436164536244065364">वेब स्टोर में देखें</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - ऑडियो चलाया जा रहा है</translation> <translation id="6442187272350399447">अद्भुत</translation> -<translation id="6442697326824312960">टैब बड़ी करें</translation> <translation id="6444070574980481588">दिनांक और समय सेट करें</translation> <translation id="6445450263907939268">यदि आप इन बदलावों को नहीं चाहते हैं, तो आप अपनी पिछली सेटिंग पुन: स्थापित कर सकते हैं.</translation> <translation id="6447842834002726250">कुकी</translation> @@ -3733,7 +3715,6 @@ <translation id="6770664076092644100">NFC के ज़रिए पुष्टि करें</translation> <translation id="6771503742377376720">एक प्रमाणन प्राधिकरण है</translation> <translation id="6777817260680419853">रीडायरेक्ट ब्लॉक किया गया</translation> -<translation id="6778959797435875428">साइटें अनम्यूट करें</translation> <translation id="677965093459947883">बहुत छोटा</translation> <translation id="6780439250949340171">अन्य सेटिंग प्रबंधित करें</translation> <translation id="6781284683813954823">डूडल का लिंक</translation> @@ -4050,7 +4031,6 @@ <translation id="7257666756905341374">कॉपी बनाया और चिपकाया जाने वाला डेटा पढ़ें</translation> <translation id="7258697411818564379">आपका पिन जोड़ दिया गया है</translation> <translation id="7262004276116528033">यह प्रवेश सेवा <ph name="SAML_DOMAIN" /> द्वारा होस्ट की गई है</translation> -<translation id="7268365133021434339">टैब बंद करें</translation> <translation id="7268659760406822741">उपलब्ध सेवाएं</translation> <translation id="7270858098575133036">जब साइट MIDI डिवाइस को एक्सेस करने के लिए सिस्टम अनन्य संदेशों का उपयोग करना चाहे, तो इसके लिए पूछें</translation> <translation id="7272674038937250585">कोई विवरण नहीं दिया गया है</translation> @@ -4240,7 +4220,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">सेट में प्रिंट करें</translation> <translation id="7576976045740938453">डेमो मोड खाते में कोई परेशानी हुई.</translation> -<translation id="7579149537961810247">साइटें म्यूट करें</translation> <translation id="7580671184200851182">सभी स्पीकर से समान ऑडियो चलाएं (मोनो ऑडियो)</translation> <translation id="7581462281756524039">क्लीनअप टूल</translation> <translation id="7582582252461552277">इस नेटवर्क को प्राथमिकता दें</translation> @@ -4594,7 +4573,6 @@ <translation id="8068253693380742035">प्रवेश करने के लिए स्पर्श करें</translation> <translation id="8069615408251337349">Google क्लाउड प्रिंट</translation> <translation id="8071432093239591881">चित्र के रूप में प्रिंट करें</translation> -<translation id="8072988827236813198">टैब छोटा करें</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />ऐप्लिकेशन डेटा ऐसा कोई भी डेटा हो सकता है जिसे किसी ऐप्लिकेशन ने (डेवलपर सेटिंग के हिसाब से) सेव किया है, इसमें संपर्क, मैसेज और फ़ोटो जैसा डेटा शामिल है.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />बैकअप डेटा को आपके बच्चे के 'डिस्क' के मेमोरी कोटा में शामिल नहीं किया जाएगा.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />आप सेटिंग में जाकर इस सेवा को बंद कर सकते हैं.<ph name="END_PARAGRAPH3" /></translation> @@ -4780,7 +4758,6 @@ <translation id="8368859634510605990">सभी बुकमार्क &खोलें</translation> <translation id="8371695176452482769">अब बोलें</translation> <translation id="8372369524088641025">ख़राब WEP कुंजी</translation> -<translation id="8373553483208508744">टैब की आवाज़ बंद करें</translation> <translation id="8378714024927312812">आपके संगठन की ओर से प्रबंधित</translation> <translation id="8379878387931047019">इस डिवाइस पर इस तरह की 'सुरक्षा चाबी' काम नहीं करती है जिसका इस वेबसाइट में अनुरोध किया गया है</translation> <translation id="8382913212082956454">ईमेल पते की कॉपी बनाएं</translation> @@ -4888,7 +4865,6 @@ <translation id="8546930481464505581">स्पर्श बार कस्टमाइज़ करें</translation> <translation id="8547013269961688403">फ़ुलस्क्रीन पर सामग्री को बड़ा दिखाने की सुविधा चालू करें</translation> <translation id="85486688517848470">शीर्ष-पंक्ति वाली कुंजियों का व्यवहार स्विच करने के लिए खोज कुंजी दबाए रखें</translation> -<translation id="855081842937141170">टैब छोटा करें</translation> <translation id="8551388862522347954">लाइसेंस</translation> <translation id="8553342806078037065">अन्य लोगों को प्रबंधित करें</translation> <translation id="8554899698005018844">कोई भाषा नहीं</translation> @@ -5202,7 +5178,6 @@ <translation id="9038430547971207796">अगली बार, आपका फ़ोन आपके <ph name="DEVICE_TYPE" /> को अनलॉक करेगा. सेटिंग में जाकर Smart Lock बंद करें.</translation> <translation id="9038649477754266430">अधिक तेज़ी से पेज लोड करने के लिए किसी पूर्वानुमान सेवा का उपयोग करें</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">टैब की आवाज़ बंद करें</translation> <translation id="9040661932550800571"><ph name="ORIGIN" /> के लिए पासवर्ड अपडेट करें?</translation> <translation id="9041692268811217999">आपके एडमिन ने आपकी मशीन पर स्थानीय फ़ाइलों की एक्सेस बंद कर दी है</translation> <translation id="9042893549633094279">निजता और सुरक्षा</translation> @@ -5300,7 +5275,6 @@ <translation id="920045321358709304"><ph name="SEARCH_ENGINE" /> खोजें</translation> <translation id="9201220332032049474">स्क्रीन लॉक विकल्प</translation> <translation id="9203398526606335860">&प्रोफ़ाइलिंग सक्षम</translation> -<translation id="9203478404496196495">टैब अनम्यूट करें</translation> <translation id="9203904171912129171">डिवाइस चुनें</translation> <translation id="9203962528777363226">इस डिवाइस के व्यवस्थापक ने नए उपयोगकर्ता जोड़े जाना अक्षम कर दिया है</translation> <translation id="9213073329713032541">ठीक से इंस्टॉल होना शुरू हो गया है.</translation>
diff --git a/chrome/app/resources/generated_resources_hr.xtb b/chrome/app/resources/generated_resources_hr.xtb index 486407d..20eb5b3 100644 --- a/chrome/app/resources/generated_resources_hr.xtb +++ b/chrome/app/resources/generated_resources_hr.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Pritisnite tipku ESCAPE za preskakanje (samo neslužbene međuverzije).</translation> <translation id="1093457606523402488">Vidljive mreže:</translation> <translation id="1094607894174825014">Zatražena je operacija čitanja ili zapisivanja s nevažećim odstupanjem na uređaju: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">Prestani zanemarivati web-lokacije</translation> <translation id="1097658378307015415">Prije nego što se prijavite, uđite kao gost da biste aktivirali mrežu <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Uvijek prevedi <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Stop (Zaustavi)</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Pomoću anonimnog prozora surfajte na webu bez spremanja povijesti pregledavanja</translation> <translation id="1213037489357051291">Postavljeno otisaka: <ph name="NUM_FINGERPRINTS" /></translation> <translation id="1215411991991485844">Dodana je nova pozadinska aplikacija</translation> -<translation id="1216654534877302979">Zanemari web-lokacije</translation> <translation id="1216659994753476700">Ne možemo pristupiti vašem profilu. Datoteke i podaci pohranjeni na tom uređaju možda su se izgubili.<ph name="BR" /> <ph name="BR" /> Morate ponovo postaviti profil.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">spremati podatke na vaš račun na Google disku</translation> <translation id="1288037062697528143">Noćno svjetlo automatski će se uključiti u suton</translation> <translation id="1288300545283011870">Svojstva govora</translation> -<translation id="1293177648337752319">Prestani zanemarivati web-lokaciju</translation> <translation id="1293264513303784526">USB-C uređaj (lijevi priključak)</translation> <translation id="1293556467332435079">Datoteke</translation> <translation id="1296497012903089238">Vrsta certifikata</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Početna je stranica web-stranica nove kartice</translation> <translation id="1436671784520050284">Nastavi s postavljanjem</translation> <translation id="1436784010935106834">Uklonjeno</translation> -<translation id="1438632560381091872">Uključi zvuk na karticama</translation> <translation id="1442392616396121389">Prefiks usmjeravanja</translation> <translation id="144283815522798837">Broj odabranih stavki: <ph name="NUMBER_OF_ITEMS_SELECTED" /></translation> <translation id="1444628761356461360">Ovom postavkom upravlja vlasnik uređaja, <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Nakon vašeg posljednjeg unosa zaporke povezana je neka druga tipkovnica. Možda pokušava ukrasti podatke o pritisnutim tipkama.</translation> <translation id="1567750922576943685">Potvrđivanjem identiteta bolje štitite svoje osobne podatke</translation> <translation id="1567993339577891801">Konzola JavaScripta</translation> -<translation id="1568067597247500137">Zanemari web-lokaciju</translation> <translation id="1568323446248056064">Otvorite postavke zaslona na uređaju</translation> <translation id="1572266655485775982">Omogućivanje Wi-Fija</translation> <translation id="1572585716423026576">Postavi kao pozadinu</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">X9.62 ECDSA potpis uz SHA-1</translation> <translation id="1644574205037202324">Povijest</translation> <translation id="1645516838734033527">Da bi zaštitio vaš <ph name="DEVICE_TYPE" />, Smart Lock zahtijeva zaključavanje zaslona na vašem telefonu.</translation> -<translation id="1646102270785326155">Sve datoteke i lokalni podaci povezani s ovim korisnikom trajno će se izbrisati nakon što se korisnik ukloni. Korisnik $1 i dalje će se moći prijaviti.</translation> <translation id="1646982517418478057">Unesite zaporku da biste kriptirali certifikat</translation> <translation id="164814987133974965">Nadzirani korisnik može pregledavati web uz vaše vodstvo. Kao upravitelj nadziranog korisnika možete <ph name="BEGIN_BOLD" />dozvoliti ili zabraniti<ph name="END_BOLD" /> određene web-lokacije, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Upravlja i time koja se stranica prikazuje prilikom pretraživanja putem višenamjenskog okvira.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Za uklanjanje aplikacija idite na Postavke > Trgovina Play > Upravljanje postavkama Androida > Aplikacije ili Upravitelj aplikacija. Zatim dodirnite aplikaciju koju želite deinstalirati (možda ćete morati prijeći prstom udesno ili ulijevo kako biste pronašli aplikaciju). Zatim dodirnite Deinstaliraj ili Onemogući.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Slanje zahtjeva u tijeku...</translation> -<translation id="1732215134274276513">Otkvači kartice</translation> <translation id="1733383495376208985">Kriptirajte sinkronizirane podatke vlastitom <ph name="BEGIN_LINK" />šifrom za sinkronizaciju<ph name="END_LINK" />. To ne uključuje načine plaćanja i adrese s Google Paya.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> možda se neće moći sam ažurirati</translation> <translation id="1736419249208073774">Istražite</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Sve datoteke</translation> <translation id="1809734401532861917">Dodaj moje oznake, povijest, zaporke i druge postavke na <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Pregled nije dostupan</translation> -<translation id="1812631533912615985">Otkvači kartice</translation> <translation id="1813278315230285598">Usluge</translation> <translation id="18139523105317219">Naziv EDI strane</translation> <translation id="1815083418640426271">Zalijepi kao običan tekst</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chromeom upravlja automatizirani testni softver.</translation> <translation id="2070909990982335904">Imena koja na početku imaju točku rezervirana su za sustav. Odaberite drugo ime.</translation> <translation id="2071393345806050157">Nema lokalne datoteke zapisnika.</translation> -<translation id="2074527029802029717">Odvoji karticu</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% baterije</translation> <translation id="2075959085554270910">Omogućuje uključivanje i isključivanje klikanja dodirom i povlačenja dodirom</translation> <translation id="2076269580855484719">Sakrij ovaj dodatak</translation> @@ -1357,7 +1348,6 @@ <translation id="3045447014237878114">Ta je web-lokacija automatski preuzela više datoteka</translation> <translation id="3046910703532196514">Web-stranica, potpuna</translation> <translation id="304747341537320566">Alati za pretvaranje teksta u govor</translation> -<translation id="304826556400666995">Uključi zvuk na karticama</translation> <translation id="3053013834507634016">Korištenje ključa certifikata</translation> <translation id="3057861065630527966">Izrada sigurnosnih kopija fotografija i videozapisa</translation> <translation id="3060379269883947824">Omogući Odabir za govor</translation> @@ -2343,7 +2333,6 @@ <translation id="4628762811416793313">Postavljanje Linuxovog spremnika nije dovršeno. Pokušajte ponovo.</translation> <translation id="4628948037717959914">Fotografija</translation> <translation id="4631887759990505102">Izvođač</translation> -<translation id="4632483769545853758">Uključi zvuk kartice</translation> <translation id="4633003931260532286">Minimalna je verzija za "<ph name="IMPORT_NAME" />" koju proširenje zahtijeva "<ph name="IMPORT_VERSION" />", ali je instalirana samo verzija "<ph name="INSTALLED_VERSION" />"</translation> <translation id="4634771451598206121">Prijavite se ponovo...</translation> <translation id="4635398712689569051">Stranica <ph name="PAGE_NAME" /> nije dostupna gostujućim korisnicima.</translation> @@ -2408,7 +2397,6 @@ <translation id="4736292055110123391">Sinkronizirajte svoje oznake, zaporke, povijest i ostalo na svim svojim uređajima</translation> <translation id="4737715515457435632">Povežite se s mrežom</translation> <translation id="473775607612524610">Ažuriraj</translation> -<translation id="474217410105706308">Isključi zvuk kartice</translation> <translation id="4742746985488890273">Prikvači na policu</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Saznajte kako ažurirati aplikacije<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Poruke</translation> @@ -2633,7 +2621,6 @@ <translation id="5094721898978802975">komunicirati sa suradničkim nativnim aplikacijama</translation> <translation id="5097002363526479830">Neuspješno povezivanje s mrežom "<ph name="NAME" />": <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Otvori sve oznake</translation> -<translation id="5105855035535475848">Prikvači kartice</translation> <translation id="5108967062857032718">Postavke – uklanjanje Android aplikacija</translation> <translation id="5109044022078737958">Blanka</translation> <translation id="5111692334209731439">&Upravitelj oznaka</translation> @@ -2698,7 +2685,6 @@ <translation id="520621735928254154">Pogreška pri uvozu certifikata</translation> <translation id="5209320130288484488">Nije pronađen nijedan uređaj</translation> <translation id="5209518306177824490">SHA-1 otisak prsta</translation> -<translation id="5210365745912300556">Zatvori karticu</translation> <translation id="5213481667492808996">Vaša podatkovna usluga "<ph name="NAME" />" spremna je za upotrebu</translation> <translation id="5213891612754844763">Prikaži postavke proxyja</translation> <translation id="521582610500777512">Fotografija je odbačena</translation> @@ -2750,7 +2736,6 @@ <translation id="5272654297705279635">Prilagođene postavke</translation> <translation id="5275352920323889391">Pas</translation> <translation id="5275973617553375938">Oporavljene datoteke s Google diska</translation> -<translation id="527605719918376753">Isključi zvuk kartice</translation> <translation id="527605982717517565">Uvijek dopusti JavaScript na web-lokaciji <ph name="HOST" /></translation> <translation id="5280426389926346830">Želite li izraditi prečac?</translation> <translation id="528208740344463258">Da biste preuzeli i upotrebljavali Android aplikacije, najprije morate instalirati ovo obavezno ažuriranje. Dok se uređaj <ph name="DEVICE_TYPE" /> ažurira, ne možete ga upotrebljavati. Uređaj <ph name="DEVICE_TYPE" /> ponovo će se pokrenuti kada instaliranje završi.</translation> @@ -2873,7 +2858,6 @@ <translation id="5449551289610225147">Nevažeća zaporka</translation> <translation id="5449588825071916739">Označi sve kartice</translation> <translation id="5449716055534515760">Close Win&dow (Zatvori prozor)</translation> -<translation id="5453029940327926427">Zatvori kartice</translation> <translation id="5454166040603940656">uz <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Nije važeće</translation> <translation id="5457459357461771897">čitati i brisati fotografije, glazbu i druge medije s vašeg računala</translation> @@ -3338,7 +3322,6 @@ <translation id="6122875415561139701">Operacija zapisivanja nije dopuštena na uređaju: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">O tom proširenju ovise sljedeća proširenja:</translation> <translation id="6125479973208104919">Nažalost, morat ćete ponovo dodati svoj račun na ovaj uređaj <ph name="DEVICE_TYPE" />.</translation> -<translation id="612596694132302162">Prestani zanemarivati web-lokaciju</translation> <translation id="6129691635767514872">Odabrani podaci uklonjeni su iz Chromea i sa sinkroniziranih uređaja. Na Google računu možda postoje drugi oblici povijesti pregledavanja, primjerice pretraživanja i aktivnosti s drugih Googleovih usluga, na stranici <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Komentar Netscape certifikata</translation> <translation id="6129953537138746214">Razmak</translation> @@ -3541,7 +3524,6 @@ <translation id="6436164536244065364">Pogledaj u web-trgovini</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – reprodukcija zvuka</translation> <translation id="6442187272350399447">Fenomenalan</translation> -<translation id="6442697326824312960">Odvoji karticu</translation> <translation id="6444070574980481588">Postavite datum i vrijeme</translation> <translation id="6445450263907939268">Ako ne želite te promjene, možete vratiti svoje prethodne postavke.</translation> <translation id="6447842834002726250">Kolačići</translation> @@ -3744,7 +3726,6 @@ <translation id="6770664076092644100">Potvrda putem NFC-a</translation> <translation id="6771503742377376720">jest tijelo za izdavanje certifikata</translation> <translation id="6777817260680419853">Preusmjeravanje je blokirano</translation> -<translation id="6778959797435875428">Prestani zanemarivati web-lokacije</translation> <translation id="677965093459947883">Vrlo mali</translation> <translation id="6780439250949340171">upravljati ostalim postavkama</translation> <translation id="6781284683813954823">Veza za doodle logotip</translation> @@ -4061,7 +4042,6 @@ <translation id="7257666756905341374">čitati podatke koje kopirate i lijepite</translation> <translation id="7258697411818564379">Vaš je PIN dodan</translation> <translation id="7262004276116528033">Tu uslugu prijave hostira <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Zatvori kartice</translation> <translation id="7268659760406822741">Dostupne usluge</translation> <translation id="7270858098575133036">Pitaj kada web-lokacija želi upotrijebiti posebne sistemske poruke za pristup MIDI uređajima</translation> <translation id="7272674038937250585">Nije naveden opis</translation> @@ -4251,7 +4231,6 @@ <translation id="7576032389798113292">6 x 4</translation> <translation id="7576690715254076113">Spari</translation> <translation id="7576976045740938453">Pojavio se problem s računom za demo način.</translation> -<translation id="7579149537961810247">Zanemari web-lokacije</translation> <translation id="7580671184200851182">Reprodukcija istog zvuka na svim zvučnicima (mono audio)</translation> <translation id="7581462281756524039">Alat za čišćenje</translation> <translation id="7582582252461552277">Preferiraj ovu mrežu</translation> @@ -4605,7 +4584,6 @@ <translation id="8068253693380742035">Dodirnite za prijavu</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Ispiši kao sliku</translation> -<translation id="8072988827236813198">Prikvači kartice</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Podaci aplikacije mogu biti bilo koji podaci koje je aplikacija spremila (na temelju postavki razvojnog programera), uključujući potencijalno osjetljive podatke kao što su kontakti, poruke i fotografije.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Podaci sigurnosne kopije ne ulaze u kvotu pohrane na Disku vašeg podređenog računa.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Tu uslugu možete isključiti u Postavkama.<ph name="END_PARAGRAPH3" /></translation> @@ -4792,7 +4770,6 @@ <translation id="8368859634510605990">&Otvori sve oznake</translation> <translation id="8371695176452482769">Govorite sad</translation> <translation id="8372369524088641025">Neispravan WEP ključ</translation> -<translation id="8373553483208508744">Isključi zvuk na karticama</translation> <translation id="8378714024927312812">Pod upravljanjem vaše organizacije</translation> <translation id="8379878387931047019">Ovaj uređaj ne podržava vrstu sigurnosnog ključa koju zahtijeva ta web-lokacija</translation> <translation id="8382913212082956454">Kopiraj &adresu e-pošte</translation> @@ -4900,7 +4877,6 @@ <translation id="8546930481464505581">Prilagodba dodirne trake</translation> <translation id="8547013269961688403">Omogući povećalo za cijeli zaslon</translation> <translation id="85486688517848470">Držite tipku Pretraživanje da biste izmjenjivali ponašanje tipki u najvišem retku</translation> -<translation id="855081842937141170">Označi karticu</translation> <translation id="8551388862522347954">Licence</translation> <translation id="8553342806078037065">Upravljaj drugim osobama</translation> <translation id="8554899698005018844">Nema jezika</translation> @@ -5215,7 +5191,6 @@ <translation id="9038430547971207796">Sljedeći će put telefon otključati vaš <ph name="DEVICE_TYPE" />. Smart Lock isključite u Postavkama.</translation> <translation id="9038649477754266430">Upotreba usluge predviđanja za brže učitavanje stranica</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Isključi zvuk na karticama</translation> <translation id="9040661932550800571">Želite li ažurirati zaporku za <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Pristup lokalnim datotekama na vašem računalu onemogućio je administrator</translation> <translation id="9042893549633094279">Privatnost i sigurnost</translation> @@ -5313,7 +5288,6 @@ <translation id="920045321358709304">Pretraži <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Opcije zaključavanja zaslona</translation> <translation id="9203398526606335860">&Profiliranje omogućeno</translation> -<translation id="9203478404496196495">Uključi zvuk kartice</translation> <translation id="9203904171912129171">Odaberite uređaj</translation> <translation id="9203962528777363226">Administrator ovog uređaja onemogućio je dodavanje novih korisnika</translation> <translation id="9213073329713032541">Instalacija je uspješno pokrenuta.</translation>
diff --git a/chrome/app/resources/generated_resources_hu.xtb b/chrome/app/resources/generated_resources_hu.xtb index c9690f9..d2374ab 100644 --- a/chrome/app/resources/generated_resources_hu.xtb +++ b/chrome/app/resources/generated_resources_hu.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Nyomja le az ESC billentyűt a kihagyáshoz (csak nem hivatalos verzióknál).</translation> <translation id="1093457606523402488">Látható hálózatok:</translation> <translation id="1094607894174825014">Az olvasási vagy írási művelet érvénytelen eltolással lett kérve a következőn: „<ph name="DEVICE_NAME" />”.</translation> -<translation id="109758035718544977">Webhelyek némításának feloldása</translation> <translation id="1097658378307015415">Kérjük, bejelentkezés előtt a(z) <ph name="NETWORK_ID" /> hálózat aktiválásához lépjen be vendégként.</translation> <translation id="1103523840287552314"><ph name="LANGUAGE" /> - mindig legyen lefordítva</translation> <translation id="1108600514891325577">&Leállítás</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Internetezzen a böngészési előzmények mentése nélkül inkognitóablakban</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> ujjlenyomat van beállítva</translation> <translation id="1215411991991485844">Új háttéralkalmazás hozzáadva</translation> -<translation id="1216654534877302979">Webhelyek némítása</translation> <translation id="1216659994753476700">Elnézést kérünk! Nem tudunk hozzáférni a profiljához. Előfordulhat, hogy az ezen az eszközön tárolt fájlok és adatok elvesztek.<ph name="BR" /> <ph name="BR" /> Ismét be kell állítania profilját.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Adattárolás a Google Drive-fiókban</translation> <translation id="1288037062697528143">Az Éjszakai fény automatikusan bekapcsol naplementekor.</translation> <translation id="1288300545283011870">Beszéd tulajdonságai</translation> -<translation id="1293177648337752319">Webhely némításának feloldása</translation> <translation id="1293264513303784526">C típusú USB-vel kompatibilis eszköz (bal oldali port)</translation> <translation id="1293556467332435079">Fájlok</translation> <translation id="1296497012903089238">Tanúsítvány típusa</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Az Új lap oldal a kezdőoldal</translation> <translation id="1436671784520050284">Beállítás folytatása</translation> <translation id="1436784010935106834">Eltávolítva</translation> -<translation id="1438632560381091872">Lapok némításának feloldása</translation> <translation id="1442392616396121389">Útvonal előtagja</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> kijelölve</translation> <translation id="1444628761356461360">Ezt a beállítást az eszköz tulajdonosa (<ph name="OWNER_EMAIL" />) kezeli.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">A jelszó utolsó megadása óta új billentyűzetet csatlakoztattak. Előfordulhat, hogy így kísérlik meg a billentyűleütések rögzítését.</translation> <translation id="1567750922576943685">Személyazonosságának igazolásával segít személyes adatainak megvédésében</translation> <translation id="1567993339577891801">JavaScript-konzol</translation> -<translation id="1568067597247500137">Webhely némítása</translation> <translation id="1568323446248056064">Megjelenítőeszköz beállításainak megnyitása</translation> <translation id="1572266655485775982">Wi-Fi engedélyezése</translation> <translation id="1572585716423026576">Beállítás háttérként</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">X9.62 ECDSA aláírás a következővel: SHA-1</translation> <translation id="1644574205037202324">Előzmények</translation> <translation id="1645516838734033527">A Smart Lock funkció a(z) <ph name="DEVICE_TYPE" /> eszköz biztonságának megőrzése érdekében előírja képernyőzár beállítását a telefonon.</translation> -<translation id="1646102270785326155">A felhasználó eltávolításakor az összes hozzá tartozó fájl és helyi adat is véglegesen törlődik. $1 továbbra is be tud jelentkezni.</translation> <translation id="1646982517418478057">Adjon meg egy jelszót a tanúsítvány titkosításához</translation> <translation id="164814987133974965">A felügyelt felhasználó az Ön engedélyei szerint böngészhet az interneten. A felügyelt felhasználó kezelőjeként Ön a következőket teheti: bizonyos webhelyek <ph name="BEGIN_BOLD" />engedélyezése vagy tiltása<ph name="END_BOLD" />, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Továbbá azt is szabályozza, hogy melyik oldal jelenik meg a cím- és keresősávban indított kereséskor.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Az alkalmazásokat a Beállítások > Google Play Áruház > Android-beállítások kezelése > Alkalmazások vagy Alkalmazáskezelő menüben távolíthatja el. Koppintson a törölni kívánt alkalmazásra (lehet, hogy jobbra vagy balra kell csúsztatnia az alkalmazásokat, hogy megtalálja), majd koppintson az Eltávolítás vagy Letiltás lehetőségre.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Lekérés küldése folyamatban...</translation> -<translation id="1732215134274276513">Lapok feloldása</translation> <translation id="1733383495376208985">A szinkronizált adatok titkosítása saját <ph name="BEGIN_LINK" />összetett szinkronizálási jelszóval<ph name="END_LINK" />. Ez nem tartalmazza a Google Payben megadott fizetési módokat és címeket.</translation> <translation id="1734824808160898225">A <ph name="PRODUCT_NAME" /> nem tudja rendszeresen frissíteni önmagát</translation> <translation id="1736419249208073774">Felfedezés</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Minden fájl</translation> <translation id="1809734401532861917">Saját könyvjelzők, előzmények, jelszavak és egyéb beállítások hozzáadása a következőhöz: <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Nincs előnézet</translation> -<translation id="1812631533912615985">Lapok feloldása</translation> <translation id="1813278315230285598">Szolgáltatások</translation> <translation id="18139523105317219">EDI fél neve</translation> <translation id="1815083418640426271">Beillesztés egyszerű szövegként</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">A Chrome-ot automatizált tesztszoftverek irányítják.</translation> <translation id="2070909990982335904">A ponttal kezdődő nevek a rendszer számára vannak fenntartva. Kérjük, válasszon másik nevet.</translation> <translation id="2071393345806050157">Nincs helyi naplófájl.</translation> -<translation id="2074527029802029717">Ne legyen rögzítve</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />%-os töltöttség</translation> <translation id="2075959085554270910">Lehetővé teszi a koppintással történő kattintás és a koppintással történő húzás engedélyezését/letiltását</translation> <translation id="2076269580855484719">Plug-in elrejtése</translation> @@ -1353,7 +1344,6 @@ <translation id="3045447014237878114">Ez a webhely automatikusan letöltött több fájlt</translation> <translation id="3046910703532196514">Weboldal -- teljes</translation> <translation id="304747341537320566">Beszédmotorok</translation> -<translation id="304826556400666995">Lapok némításának feloldása</translation> <translation id="3053013834507634016">Tanúsítványkulcs felhasználása</translation> <translation id="3057861065630527966">Biztonsági másolat készítése a fotókról és videókról</translation> <translation id="3060379269883947824">Felolvasás engedélyezése</translation> @@ -2335,7 +2325,6 @@ <translation id="4628762811416793313">A Linux-tároló beállítása nem fejeződött be. Próbálja újra.</translation> <translation id="4628948037717959914">Fénykép</translation> <translation id="4631887759990505102">Előadó</translation> -<translation id="4632483769545853758">Lap némításának feloldása</translation> <translation id="4633003931260532286">A bővítmény a(z) „<ph name="IMPORT_NAME" />” legalább „<ph name="IMPORT_VERSION" />” verzióját igényli, ám csak a(z) „<ph name="INSTALLED_VERSION" />” verzió van telepítve</translation> <translation id="4634771451598206121">Bejelentkezés újra...</translation> <translation id="4635398712689569051">A(z) <ph name="PAGE_NAME" /> nem hozzáférhető a vendég felhasználók számára.</translation> @@ -2399,7 +2388,6 @@ <translation id="4735803855089279419">A rendszer nem tudta megállapítani az eszközazonosítókat ehhez az eszközhöz.</translation> <translation id="4737715515457435632">Kérjük, csatlakozzon egy hálózathoz</translation> <translation id="473775607612524610">Frissítés</translation> -<translation id="474217410105706308">Lap némítása</translation> <translation id="4742746985488890273">Rögzítés a polcra</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />További információ az alkalmazások frissítéséről<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Üzenetek</translation> @@ -2624,7 +2612,6 @@ <translation id="5094721898978802975">Kommunikáció az együttműködő natív alkalmazásokkal</translation> <translation id="5097002363526479830">Nem sikerült csatlakozni a(z) <ph name="NAME" /> hálózathoz: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Az összes könyvjelző megnyitása</translation> -<translation id="5105855035535475848">Lapok rögzítése</translation> <translation id="5108967062857032718">Beállítások – Android-alkalmazások eltávolítása</translation> <translation id="5109044022078737958">Sport</translation> <translation id="5111692334209731439">&Könyvjelzőkezelő</translation> @@ -2689,7 +2676,6 @@ <translation id="520621735928254154">Tanúsítványimportálási hiba</translation> <translation id="5209320130288484488">Nem találhatók eszközök</translation> <translation id="5209518306177824490">SHA-1 ujjlenyomat</translation> -<translation id="5210365745912300556">Lap bezárása</translation> <translation id="5213481667492808996">„<ph name="NAME" />” adatszolgáltatása készen áll a használatra</translation> <translation id="5213891612754844763">Proxybeállítások megjelenítése</translation> <translation id="521582610500777512">A fotót elvetették</translation> @@ -2740,7 +2726,6 @@ <translation id="5270167208902136840"><ph name="NUMBER_OF_MORE_APPS" /> további alkalmazás megjelenítése</translation> <translation id="5275352920323889391">Kutya</translation> <translation id="5275973617553375938">A Google Drive-ról visszaállított fájlok</translation> -<translation id="527605719918376753">Lap némítása</translation> <translation id="527605982717517565">Mindig engedélyezze a JavaScriptet itt: <ph name="HOST" /></translation> <translation id="5280426389926346830">Létrehozza a parancsikont?</translation> <translation id="528208740344463258">Androidos alkalmazások letöltéséhez és használatához először telepítenie kell ezt a kötelező frissítést. Miközben <ph name="DEVICE_TYPE" /> eszköze frissít, nem használhatja. A telepítés befejeződését követően <ph name="DEVICE_TYPE" /> eszköze újraindul.</translation> @@ -2864,7 +2849,6 @@ <translation id="5449551289610225147">Érvénytelen jelszó</translation> <translation id="5449588825071916739">Összes lap hozzáadása a könyvjelzőkhöz</translation> <translation id="5449716055534515760">A&blak bezárása</translation> -<translation id="5453029940327926427">Lapok bezárása</translation> <translation id="5454166040603940656"><ph name="PROVIDER" /> szolgáltatóval</translation> <translation id="5457113250005438886">Érvénytelen</translation> <translation id="5457459357461771897">Fotók, zeneszámok és más médiatartalmak olvasása és törlése a számítógépről</translation> @@ -3330,7 +3314,6 @@ <translation id="6122875415561139701">Az írási művelet nem engedélyezett a következőn: „<ph name="DEVICE_NAME" />”.</translation> <translation id="6124650939968185064">Ettől a bővítménytől a következő bővítmények függnek:</translation> <translation id="6125479973208104919">Sajnos ismét hozzá kell adnia fiókját a(z) <ph name="DEVICE_TYPE" /> eszközhöz.</translation> -<translation id="612596694132302162">Webhely némításának feloldása</translation> <translation id="6129691635767514872">A kiválasztott adatokat eltávolítottuk a Chrome-ból és a szinkronizált eszközökről. Előfordulhat, hogy Google-fiókjában (a <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> címen) még szerepelnek a böngészési előzmények egyéb formái, például az egyéb Google-szolgáltatásokban végzett keresései és tevékenységei.</translation> <translation id="6129938384427316298">Netscape tanúsítvány - megjegyzés</translation> <translation id="6129953537138746214">Szóköz</translation> @@ -3533,7 +3516,6 @@ <translation id="6436164536244065364">Megtekintés az Internetes áruházban</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – Hanglejátszás</translation> <translation id="6442187272350399447">Remek!</translation> -<translation id="6442697326824312960">Ne legyen rögzítve</translation> <translation id="6444070574980481588">Dátum és idő beállítása</translation> <translation id="6445450263907939268">Ha nem szándékosan végezte el ezeket a módosításokat, visszaállíthatja korábbi beállításait.</translation> <translation id="6447842834002726250">Cookie-k</translation> @@ -3736,7 +3718,6 @@ <translation id="6770664076092644100">Igazolás NFC-n keresztül</translation> <translation id="6771503742377376720">Tanúsítványkibocsátó</translation> <translation id="6777817260680419853">Átirányítás letiltva</translation> -<translation id="6778959797435875428">Webhelyek némításának feloldása</translation> <translation id="677965093459947883">Nagyon kicsi</translation> <translation id="6780439250949340171">egyéb beállítások kezelése</translation> <translation id="6781284683813954823">Ünnepi embléma linkje</translation> @@ -4053,7 +4034,6 @@ <translation id="7257666756905341374">Az Ön által másolt és beillesztett adatok olvasása</translation> <translation id="7258697411818564379">PIN-kód beállítva</translation> <translation id="7262004276116528033">Ezt a bejelentkezési szolgáltatást a(z) <ph name="SAML_DOMAIN" /> biztosítja</translation> -<translation id="7268365133021434339">Lapok bezárása</translation> <translation id="7268659760406822741">Igénybe vehető szolgáltatások</translation> <translation id="7270858098575133036">Kérdezzen meg, amikor egy webhely exkluzív rendszerüzenetekkel szeretné elérni a MIDI-eszközöket</translation> <translation id="7272674038937250585">Nincs leírás</translation> @@ -4243,7 +4223,6 @@ <translation id="7576032389798113292">6×4</translation> <translation id="7576690715254076113">Szétválogatás</translation> <translation id="7576976045740938453">Gond adódott a demó módban lévő fiókkal.</translation> -<translation id="7579149537961810247">Webhelyek némítása</translation> <translation id="7580671184200851182">Azonos hang lejátszása mindegyik hangszórón (monó hang)</translation> <translation id="7581462281756524039">Egy karbantartó eszköz</translation> <translation id="7582582252461552277">Ezt a hálózatot részesítse előnyben</translation> @@ -4597,7 +4576,6 @@ <translation id="8068253693380742035">Érintse meg a bejelentkezéshez</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Nyomtatás képként</translation> -<translation id="8072988827236813198">Lapok rögzítése</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Alkalmazásadat lehet minden olyan adat, amelyet valamelyik alkalmazás elmentett (a fejlesztői beállítások alapján), beleértve például a névjegyeket, az üzeneteket és a fotókat.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />A biztonsági másolat adatai nem számítanak bele gyermeke Drive-tárhelykvótájába.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Ezt a szolgáltatást a Beállítások között kapcsolhatja ki.<ph name="END_PARAGRAPH3" /></translation> @@ -4783,7 +4761,6 @@ <translation id="8368859634510605990">&Az összes könyvjelző megnyitása</translation> <translation id="8371695176452482769">Most beszéljen</translation> <translation id="8372369524088641025">Hibás WEP kulcs</translation> -<translation id="8373553483208508744">Lapok némítása</translation> <translation id="8378714024927312812">Az Ön szervezete kezeli</translation> <translation id="8379878387931047019">Az eszköz nem támogatja a webhely által kért biztonsági hardverkulcstípust</translation> <translation id="8382913212082956454">&E-mail cím másolása</translation> @@ -4891,7 +4868,6 @@ <translation id="8546930481464505581">Az érintősáv személyre szabása</translation> <translation id="8547013269961688403">Teljes képernyős nagyító engedélyezése</translation> <translation id="85486688517848470">A legfelső billentyűsor viselkedésének módosításához tartsa lenyomva a keresőgombot</translation> -<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> @@ -5205,7 +5181,6 @@ <translation id="9038430547971207796">A következő alkalommal a telefonnal oldhatja fel a <ph name="DEVICE_TYPE" /> lezárását. A Smart Lock funkciót a Beállításokban kapcsolhatja ki.</translation> <translation id="9038649477754266430">A várható kifejezés szolgáltatás használata az oldalak gyorsabb betöltése érdekében</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Lapok némítása</translation> <translation id="9040661932550800571">Szeretné frissíteni a(z) <ph name="ORIGIN" /> jelszavát?</translation> <translation id="9041692268811217999">A rendszergazda letiltotta a számítógép helyi fájljaihoz való hozzáférést</translation> <translation id="9042893549633094279">Adatvédelem és biztonság</translation> @@ -5303,7 +5278,6 @@ <translation id="920045321358709304">Keresés a következővel: <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">A képernyőzár beállításai</translation> <translation id="9203398526606335860">&Profilozás bekapcsolva</translation> -<translation id="9203478404496196495">Lap némításának feloldása</translation> <translation id="9203904171912129171">Válassza ki a kívánt eszközt</translation> <translation id="9203962528777363226">Az eszköz rendszergazdája letiltotta az új felhasználók hozzáadását</translation> <translation id="9213073329713032541">Telepítés sikeresen megkezdve.</translation>
diff --git a/chrome/app/resources/generated_resources_id.xtb b/chrome/app/resources/generated_resources_id.xtb index 7a6434cc..f1ea019c 100644 --- a/chrome/app/resources/generated_resources_id.xtb +++ b/chrome/app/resources/generated_resources_id.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Tekan ESCAPE untuk melewati (Khusus bentukan tidak resmi).</translation> <translation id="1093457606523402488">Jaringan yang Terlihat:</translation> <translation id="1094607894174825014">Operasi baca atau tulis diminta dengan offset yang tidak valid di: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">Nyalakan Notifikasi Situs</translation> <translation id="1097658378307015415">Sebelum masuk, masuklah sebagai Tamu untuk mengaktifkan jaringan <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Selalu terjemahkan <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Berhenti</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Gunakan web tanpa menyimpan histori browsing dengan jendela samaran</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> sidik jari disiapkan</translation> <translation id="1215411991991485844">Apl latar belakang yang baru telah ditambahkan</translation> -<translation id="1216654534877302979">Matikan notifikasi situs</translation> <translation id="1216659994753476700">Maaf, kami tidak dapat mengakses profil Anda. File dan data yang disimpan di perangkat ini mungkin telah hilang.<ph name="BR" /> <ph name="BR" /> Anda harus menyiapkan kembali profil Anda.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Simpan data di akun Google Drive Anda</translation> <translation id="1288037062697528143">Fitur Cahaya Malam akan otomatis aktif saat matahari terbenam</translation> <translation id="1288300545283011870">Properti Ucapan</translation> -<translation id="1293177648337752319">Nyalakan Notifikasi Situs</translation> <translation id="1293264513303784526">Perangkat USB-C (port sebelah kiri)</translation> <translation id="1293556467332435079">File</translation> <translation id="1296497012903089238">Jenis Sertifikat</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Beranda adalah halaman Tab Baru</translation> <translation id="1436671784520050284">Lanjutkan penyiapan</translation> <translation id="1436784010935106834">Dihapus</translation> -<translation id="1438632560381091872">Nonaktifkan tab</translation> <translation id="1442392616396121389">Prefiks perutean</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> dipilih</translation> <translation id="1444628761356461360">Setelan ini dikelola oleh pemilik perangkat, <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Keyboard yang berbeda telah terhubung sejak Anda terakhir memasukkan sandi. Keyboard tersebut mungkin mencoba mencuri ketukan tombol Anda.</translation> <translation id="1567750922576943685">Memverifikasi identitas membantu melindungi informasi pribadi Anda</translation> <translation id="1567993339577891801">Konsol Javascript</translation> -<translation id="1568067597247500137">Matikan notifikasi situs</translation> <translation id="1568323446248056064">Buka setelan perangkat layar</translation> <translation id="1572266655485775982">Wi-Fi aktif</translation> <translation id="1572585716423026576">Setel sebagai wallpaper</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">Tanda tangan X9.62 ECDSA dengan SHA-1</translation> <translation id="1644574205037202324">Histori</translation> <translation id="1645516838734033527">Agar <ph name="DEVICE_TYPE" /> tetap aman, Smart Lock memerlukan kunci layar pada ponsel Anda.</translation> -<translation id="1646102270785326155">Setelah pengguna ini dihapus, semua file dan data lokal yang dikaitkan ke pengguna ini akan dihapus secara permanen. $1 tetap dapat masuk lagi nanti.</translation> <translation id="1646982517418478057">Masukkan sandi untuk mengenkripsi sertifikat ini</translation> <translation id="164814987133974965">Pengguna yang diawasi dapat menjelajahi web dengan panduan Anda. Sebagai pengelola pengguna yang dilindungi, Anda dapat <ph name="BEGIN_BOLD" />mengizinkan atau melarang<ph name="END_BOLD" /> situs web tertentu, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Juga mengontrol halaman apa yang ditampilkan saat Anda menelusuri dari Omnibox.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Untuk menghapus aplikasi, buka Setelan > Google Play Store > Kelola preferensi Android > Aplikasi atau Pengelola aplikasi. Lalu, tap aplikasi yang ingin diuninstal (Anda mungkin perlu menggeser ke kanan atau ke kiri untuk mencari aplikasi). Selanjutnya, tap Uninstal atau Nonaktifkan.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Mengirimkan permintaan...</translation> -<translation id="1732215134274276513">Lepas Sematan Tab</translation> <translation id="1733383495376208985">Enkripsikan data yang disinkronkan dengan <ph name="BEGIN_LINK" />frasa sandi siknronisasi<ph name="END_LINK" /> Anda sendiri. Data ini tidak mencakup alamat dan metode pembayaran dari Google Pay.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> mungkin tidak dapat diupdate secara otomatis</translation> <translation id="1736419249208073774">Jelajahi</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Semua file</translation> <translation id="1809734401532861917">Tambahkan bookmark, histori, sandi, dan setelan saya lainnya ke <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Tidak ada pratinjau yang tersedia</translation> -<translation id="1812631533912615985">Lepas sematan tab</translation> <translation id="1813278315230285598">Layanan</translation> <translation id="18139523105317219">EDI Party Name</translation> <translation id="1815083418640426271">Tempel Sebagai Teks Biasa</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chrome sedang dikontrol oleh software uji otomatis.</translation> <translation id="2070909990982335904">Nama yang dimulai dengan titik hanya untuk sistem. Harap pilih nama yang lain.</translation> <translation id="2071393345806050157">Tidak ada file log lokal.</translation> -<translation id="2074527029802029717">Lepas sematan tab</translation> <translation id="2075474481720804517">Baterai <ph name="BATTERY_PERCENTAGE" />%</translation> <translation id="2075959085554270910">Memungkinkan Anda untuk mengaktifkan/menonaktifkan fitur tap untuk mengklik dan tap tarik</translation> <translation id="2076269580855484719">Sembunyikan plugin ini</translation> @@ -1357,7 +1348,6 @@ <translation id="3045447014237878114">Situs ini mendownload beberapa file secara otomatis</translation> <translation id="3046910703532196514">Halaman Web, Lengkap</translation> <translation id="304747341537320566">Mesin Ucapan</translation> -<translation id="304826556400666995">Nonaktifkan Tab</translation> <translation id="3053013834507634016">Penggunaan Kunci Sertifikat</translation> <translation id="3057861065630527966">Cadangkan foto dan video</translation> <translation id="3060379269883947824">Aktifkan fitur klik untuk diucapkan</translation> @@ -2343,7 +2333,6 @@ <translation id="4628762811416793313">Penyiapan container Linux tidak selesai. Harap coba lagi.</translation> <translation id="4628948037717959914">Foto</translation> <translation id="4631887759990505102">Artis</translation> -<translation id="4632483769545853758">Aktifkan Tab</translation> <translation id="4633003931260532286">Ekstensi memerlukan "<ph name="IMPORT_NAME" />" dengan versi minimum "<ph name="IMPORT_VERSION" />", namun hanya versi "<ph name="INSTALLED_VERSION" />" yang terinstal</translation> <translation id="4634771451598206121">Masuk lagi...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> tidak tersedia bagi pengguna Tamu.</translation> @@ -2408,7 +2397,6 @@ <translation id="4736292055110123391">Sinkronisasikan bookmark, sandi, histori, dan lainnya di semua perangkat Anda</translation> <translation id="4737715515457435632">Sambungkan ke jaringan</translation> <translation id="473775607612524610">Perbarui</translation> -<translation id="474217410105706308">Nonaktifkan Tab</translation> <translation id="4742746985488890273">Pin ke Rak</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Pelajari cara mengupdate aplikasi<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Pesan</translation> @@ -2633,7 +2621,6 @@ <translation id="5094721898978802975">Berkomunikasi dengan aplikasi asli yang kooperatif</translation> <translation id="5097002363526479830">Gagal menyambung ke jaringan '<ph name="NAME" />': <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Buka semua bookmark</translation> -<translation id="5105855035535475848">Sematkan tab</translation> <translation id="5108967062857032718">Setelan - Hapus aplikasi Android</translation> <translation id="5109044022078737958">Susanti</translation> <translation id="5111692334209731439">Pengelola &Bookmark</translation> @@ -2698,7 +2685,6 @@ <translation id="520621735928254154">Kesalahan Impor Sertifikat</translation> <translation id="5209320130288484488">Perangkat tidak ditemukan</translation> <translation id="5209518306177824490">SHA-1 Fingerprint</translation> -<translation id="5210365745912300556">Tutup tab</translation> <translation id="5213481667492808996">Layanan data '<ph name="NAME" />' Anda sudah siap digunakan</translation> <translation id="5213891612754844763">Tampilkan setelan proxy</translation> <translation id="521582610500777512">Foto dibuang</translation> @@ -2750,7 +2736,6 @@ <translation id="5272654297705279635">Setelan kustom</translation> <translation id="5275352920323889391">Anjing</translation> <translation id="5275973617553375938">File yang dipulihkan dari Google Drive</translation> -<translation id="527605719918376753">Nonaktifkan tab</translation> <translation id="527605982717517565">Selalu izinkan JavaScript di <ph name="HOST" /></translation> <translation id="5280426389926346830">Buat pintasan?</translation> <translation id="528208740344463258">Untuk mendownload dan menggunakan aplikasi Android, Anda harus menginstal update yang diperlukan terlebih dahulu. Saat <ph name="DEVICE_TYPE" /> sedang diupdate, Anda tidak dapat menggunakannya. Setelah penginstalan selesai, <ph name="DEVICE_TYPE" /> akan dimulai ulang.</translation> @@ -2873,7 +2858,6 @@ <translation id="5449551289610225147">Sandi tidak valid</translation> <translation id="5449588825071916739">Bookmark Semua Tab</translation> <translation id="5449716055534515760">Tutup Jen&dela</translation> -<translation id="5453029940327926427">Tutup tab</translation> <translation id="5454166040603940656">dengan <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Tidak valid</translation> <translation id="5457459357461771897">Membaca dan menghapus foto, musik, serta media lain dari komputer Anda</translation> @@ -3338,7 +3322,6 @@ <translation id="6122875415561139701">Operasi menulis tidak diizinkan di: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">Ekstensi berikut bergantung pada ekstensi ini:</translation> <translation id="6125479973208104919">Sayangnya, Anda harus menambahkan akun ke perangkat <ph name="DEVICE_TYPE" /> ini lagi.</translation> -<translation id="612596694132302162">Nyalakan notifikasi situs</translation> <translation id="6129691635767514872">Data yang dipilih telah dihapus dari Chrome dan perangkat yang disinkronkan. Akun Google Anda mungkin memiliki bentuk histori browsing lain seperti penelusuran dan aktivitas dari layanan Google lainnya di <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Netscape Certificate Comment</translation> <translation id="6129953537138746214">Spasi</translation> @@ -3541,7 +3524,6 @@ <translation id="6436164536244065364">Lihat di Toko Web</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - Pemutaran audio</translation> <translation id="6442187272350399447">Si Keren</translation> -<translation id="6442697326824312960">Lepas Sematan Tab</translation> <translation id="6444070574980481588">Setel tanggal dan waktu</translation> <translation id="6445450263907939268">Jika Anda tidak menginginkan perubahan ini, pulihkan setelan sebelumnya.</translation> <translation id="6447842834002726250">Cookie</translation> @@ -3744,7 +3726,6 @@ <translation id="6770664076092644100">Verifikasi melalui NFC</translation> <translation id="6771503742377376720">Adalah Otoritas Sertifikasi</translation> <translation id="6777817260680419853">Pengalihan diblokir</translation> -<translation id="6778959797435875428">Nyalakan notifikasi situs</translation> <translation id="677965093459947883">Sangat kecil</translation> <translation id="6780439250949340171">kelola setelan lain</translation> <translation id="6781284683813954823">Link Doodle</translation> @@ -4061,7 +4042,6 @@ <translation id="7257666756905341374">Mengakses data yang Anda salin dan tempel</translation> <translation id="7258697411818564379">PIN Anda ditambahkan</translation> <translation id="7262004276116528033">Layanan masuk ini dihosting oleh <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Tutup Tab</translation> <translation id="7268659760406822741">Layanan yang tersedia</translation> <translation id="7270858098575133036">Tanyakan saat situs ingin menggunakan pesan eksklusif sistem untuk mengakses perangkat MIDI</translation> <translation id="7272674038937250585">Tidak tersedia deskripsi</translation> @@ -4251,7 +4231,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">Padukan</translation> <translation id="7576976045740938453">Terjadi masalah dengan akun mode demo.</translation> -<translation id="7579149537961810247">Matikan Notifikasi Situs</translation> <translation id="7580671184200851182">Putar audio yang sama melalui semua speaker (audio mono)</translation> <translation id="7581462281756524039">Alat pembersih</translation> <translation id="7582582252461552277">Pilih jaringan ini</translation> @@ -4605,7 +4584,6 @@ <translation id="8068253693380742035">Sentuh untuk login</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Cetak sebagai gambar</translation> -<translation id="8072988827236813198">Sematkan Tab</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Data aplikasi dapat berupa data apa pun yang telah disimpan oleh aplikasi (berdasarkan setelan developer), termasuk data seperti kontak, pesan, dan foto.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Data backup tidak akan mengurangi kuota penyimpanan Drive anak Anda.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Anda dapat menonaktifkan layanan ini di Setelan.<ph name="END_PARAGRAPH3" /></translation> @@ -4791,7 +4769,6 @@ <translation id="8368859634510605990">&Buka semua bookmark</translation> <translation id="8371695176452482769">Bicaralah sekarang</translation> <translation id="8372369524088641025">Kunci WEP yang buruk</translation> -<translation id="8373553483208508744">Nonaktifkan tab</translation> <translation id="8378714024927312812">Dikelola oleh organisasi</translation> <translation id="8379878387931047019">Perangkat ini tidak mendukung jenis kunci keamanan yang diminta oleh situs ini</translation> <translation id="8382913212082956454">Salin alamat &email</translation> @@ -4899,7 +4876,6 @@ <translation id="8546930481464505581">Sesuaikan Touch Bar</translation> <translation id="8547013269961688403">Aktifkan kaca pembesar layar penuh</translation> <translation id="85486688517848470">Tahan tombol Penelusuran untuk mengalihkan perilaku tombol baris atas</translation> -<translation id="855081842937141170">Pasang pin pada tab</translation> <translation id="8551388862522347954">Lisensi</translation> <translation id="8553342806078037065">Kelola orang lain</translation> <translation id="8554899698005018844">Tidak ada bahasa</translation> @@ -5214,7 +5190,6 @@ <translation id="9038430547971207796">Lain kali, ponsel akan membuka kunci <ph name="DEVICE_TYPE" /> Anda. Nonaktifkan Smart Lock di Setelan.</translation> <translation id="9038649477754266430">Gunakan layanan prediksi agar halaman dimuat dengan lebih cepat</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Nonaktifkan Tab</translation> <translation id="9040661932550800571">Perbarui sandi untuk <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Akses ke file lokal di komputer Anda dinonaktifkan oleh administrator</translation> <translation id="9042893549633094279">Privasi dan keamanan</translation> @@ -5312,7 +5287,6 @@ <translation id="920045321358709304">Penelusuran <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Opsi kunci layar</translation> <translation id="9203398526606335860">&Penyidikan diaktifkan</translation> -<translation id="9203478404496196495">Aktifkan tab</translation> <translation id="9203904171912129171">Pilih perangkat</translation> <translation id="9203962528777363226">Administrator perangkat ini telah menonaktifkan pengguna baru agar tidak ditambahkan</translation> <translation id="9213073329713032541">Penginstalan berhasil dimulai.</translation>
diff --git a/chrome/app/resources/generated_resources_it.xtb b/chrome/app/resources/generated_resources_it.xtb index 82d90dd..04d8d2f 100644 --- a/chrome/app/resources/generated_resources_it.xtb +++ b/chrome/app/resources/generated_resources_it.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Premi ESC per saltare (solo build non ufficiali).</translation> <translation id="1093457606523402488">Reti visibili:</translation> <translation id="1094607894174825014">L'operazione di lettura o scrittura è stata richiesta con un offset non valido su: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">Riattiva l'audio dei siti</translation> <translation id="1097658378307015415">Prima di accedere, entra come Ospite per attivare la rete <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Traduci sempre <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Interrompi</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Apri una finestra di navigazione in incognito per esplorare il Web senza salvare la tua cronologia di navigazione</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> impronte digitali configurate</translation> <translation id="1215411991991485844">Nuova applicazione in background aggiunta</translation> -<translation id="1216654534877302979">Disattiva l'audio dei siti</translation> <translation id="1216659994753476700">Spiacenti, non riusciamo ad accedere al tuo profilo. I file e i dati memorizzati su questo dispositivo potrebbero essere andati persi.<ph name="BR" /> <ph name="BR" /> Devi configurare nuovamente il profilo.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Memorizza dati nel tuo account Google Drive</translation> <translation id="1288037062697528143">La funzione Luminosità notturna verrà attivata automaticamente al tramonto</translation> <translation id="1288300545283011870">Proprietà voce</translation> -<translation id="1293177648337752319">Riattiva l'audio del sito</translation> <translation id="1293264513303784526">Dispositivo USB-C (porta a sinistra)</translation> <translation id="1293556467332435079">File</translation> <translation id="1296497012903089238">Tipo di certificato</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">La pagina iniziale è la pagina Nuova scheda</translation> <translation id="1436671784520050284">Continua configurazione</translation> <translation id="1436784010935106834">Rimosso</translation> -<translation id="1438632560381091872">Riattiva audio schede</translation> <translation id="1442392616396121389">Prefisso di routing</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> selezionati</translation> <translation id="1444628761356461360">Questa impostazione è controllata dal proprietario del dispositivo, <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">È stata collegata una tastiera diversa dall'ultimo inserimento della password. Potrebbe essere un tentativo di rubare i tasti premuti.</translation> <translation id="1567750922576943685">La verifica della tua identità aiuta a proteggere le tue informazioni personali</translation> <translation id="1567993339577891801">Console JavaScript</translation> -<translation id="1568067597247500137">Disattiva l'audio del sito</translation> <translation id="1568323446248056064">Apri le impostazioni dello schermo</translation> <translation id="1572266655485775982">Attiva Wi-Fi</translation> <translation id="1572585716423026576">Imposta come sfondo</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">Firma X9.62 ECDSA con SHA-1</translation> <translation id="1644574205037202324">Cronologia</translation> <translation id="1645516838734033527">Per proteggere il tuo dispositivo <ph name="DEVICE_TYPE" />, la funzione Smart Lock richiede l'impostazione di un blocco schermo sul telefono.</translation> -<translation id="1646102270785326155">Tutti i file e i dati locali associati all'utente verranno eliminati definitivamente in seguito alla rimozione dell'utente. $1 potrà ancora accedere in un secondo momento.</translation> <translation id="1646982517418478057">Inserisci una password per criptare il certificato</translation> <translation id="164814987133974965">Un utente supervisionato può navigare sul Web sotto la tua guida. In qualità di gestore di un utente supervisionato puoi <ph name="BEGIN_BOLD" />consentire o vietare<ph name="END_BOLD" /> siti web specifici, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Controlla anche la pagina visualizzata quando esegui ricerche dalla Omnibox.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Per rimuovere le app apri Impostazioni > Google Play Store > Gestisci le preferenze Android > App o Gestione applicazioni, quindi tocca l'app che vuoi disinstallare (potresti dover scorrere verso sinistra o verso destra per trovarla) e infine tocca Disinstalla o Disattiva.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Invio richiesta in corso...</translation> -<translation id="1732215134274276513">Sblocca le schede</translation> <translation id="1733383495376208985">Cripta i dati sincronizzati con la tua <ph name="BEGIN_LINK" />passphrase di sincronizzazione<ph name="END_LINK" />. Non sono inclusi i metodi di pagamento e gli indirizzi di Google Pay.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> potrebbe non essere in grado di aggiornarsi automaticamente</translation> <translation id="1736419249208073774">Esplora</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Tutti i file</translation> <translation id="1809734401532861917">Aggiungi preferiti, cronologia, password e altre impostazioni a <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Anteprima non disponibile</translation> -<translation id="1812631533912615985">Sblocca le schede</translation> <translation id="1813278315230285598">Servizi</translation> <translation id="18139523105317219">EDI Party Name</translation> <translation id="1815083418640426271">Incolla come solo testo</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chrome è controllato da software di test automatizzato.</translation> <translation id="2070909990982335904">I nomi che iniziano con il punto sono riservati al sistema. Scegli un altro nome.</translation> <translation id="2071393345806050157">Nessun file di log locale.</translation> -<translation id="2074527029802029717">Sblocca scheda</translation> <translation id="2075474481720804517">Batteria al <ph name="BATTERY_PERCENTAGE" />%</translation> <translation id="2075959085554270910">Consente di attivare/disattivare il tocco per fare clic e il trascinamento al tocco</translation> <translation id="2076269580855484719">Nascondi questo plug-in</translation> @@ -797,7 +788,7 @@ <translation id="2199298570273670671">Errore</translation> <translation id="2200094388063410062">Email</translation> <translation id="2200356397587687044">Chrome ha bisogno dell'autorizzazione per continuare</translation> -<translation id="2200603218210188859">Preferenze per il dispositivo USB.</translation> +<translation id="2200603218210188859">Preferenze per il dispositivo USB</translation> <translation id="220138918934036434">Nascondi pulsante</translation> <translation id="2202898655984161076">Si è verificato un problema nella visualizzazione dell'elenco di stampanti. È possibile che alcune stampanti non siano state registrate correttamente con <ph name="CLOUD_PRINT_NAME" />.</translation> <translation id="2203682048752833055">Motore di ricerca utilizzato nella <ph name="BEGIN_LINK" />barra degli indirizzi<ph name="END_LINK" /></translation> @@ -1350,7 +1341,6 @@ <translation id="3045447014237878114">Questo sito ha scaricato automaticamente più file</translation> <translation id="3046910703532196514">Pagina web, completa</translation> <translation id="304747341537320566">Motori di riconoscimento vocale</translation> -<translation id="304826556400666995">Riattiva audio schede</translation> <translation id="3053013834507634016">Uso della chiave del certificato</translation> <translation id="3057861065630527966">Effettua il backup di foto e video</translation> <translation id="3060379269883947824">Attiva Seleziona per ascoltare</translation> @@ -2331,7 +2321,6 @@ <translation id="4628762811416793313">La configurazione del container Linux non è stata completata. Riprova.</translation> <translation id="4628948037717959914">Foto</translation> <translation id="4631887759990505102">Artista</translation> -<translation id="4632483769545853758">Riattiva audio scheda</translation> <translation id="4633003931260532286">L'estensione richiede "<ph name="IMPORT_NAME" />" con la versione minima "<ph name="IMPORT_VERSION" />", ma è installata soltanto la versione "<ph name="INSTALLED_VERSION" />"</translation> <translation id="4634771451598206121">Esegui di nuovo l'accesso...</translation> <translation id="4635398712689569051">La pagina <ph name="PAGE_NAME" /> non è disponibile per gli utenti Ospite.</translation> @@ -2395,7 +2384,6 @@ <translation id="4735803855089279419">Il sistema non è riuscito a stabilire gli identificatori di questo dispositivo.</translation> <translation id="4737715515457435632">Collegati a una rete</translation> <translation id="473775607612524610">Aggiorna</translation> -<translation id="474217410105706308">Disattiva audio scheda</translation> <translation id="4742746985488890273">Fissa sullo shelf</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Scopri come aggiornare le applicazioni<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Messaggi</translation> @@ -2620,7 +2608,6 @@ <translation id="5094721898978802975">Comunicazione con applicazioni native interoperative</translation> <translation id="5097002363526479830">Connessione alla rete "<ph name="NAME" />" non riuscita: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Apri tutti i Preferiti</translation> -<translation id="5105855035535475848">Blocca le schede</translation> <translation id="5108967062857032718">Impostazioni - Rimuovi app Android</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">&Gestione Preferiti</translation> @@ -2685,7 +2672,6 @@ <translation id="520621735928254154">Errore di importazione del certificato</translation> <translation id="5209320130288484488">Nessun dispositivo trovato</translation> <translation id="5209518306177824490">Impronta digitale SHA-1</translation> -<translation id="5210365745912300556">Chiudi scheda</translation> <translation id="5213481667492808996">Il tuo servizio dati "<ph name="NAME" />" è pronto all'uso</translation> <translation id="5213891612754844763">Mostra impostazioni proxy</translation> <translation id="521582610500777512">La foto è stata eliminata</translation> @@ -2735,7 +2721,6 @@ <translation id="5270167208902136840">Mostra altre <ph name="NUMBER_OF_MORE_APPS" /> app</translation> <translation id="5275352920323889391">Cane</translation> <translation id="5275973617553375938">File recuperati da Google Drive</translation> -<translation id="527605719918376753">Disattiva audio scheda</translation> <translation id="527605982717517565">Consenti sempre JavaScript su <ph name="HOST" /></translation> <translation id="5280426389926346830">Vuoi creare una scorciatoia?</translation> <translation id="528208740344463258">Per scaricare e utilizzare le app Android, devi prima installare questo aggiornamento obbligatorio. Mentre il tuo dispositivo <ph name="DEVICE_TYPE" /> viene aggiornato, non puoi utilizzarlo. Il dispositivo <ph name="DEVICE_TYPE" /> verrà riavviato al termine dell'installazione.</translation> @@ -2858,7 +2843,6 @@ <translation id="5449551289610225147">Password non valida</translation> <translation id="5449588825071916739">Aggiungi tutte le schede ai Preferiti</translation> <translation id="5449716055534515760">Chiu&di finestra</translation> -<translation id="5453029940327926427">Chiudi schede</translation> <translation id="5454166040603940656">con <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Non validi</translation> <translation id="5457459357461771897">Lettura ed eliminazione di foto, musica e altri contenuti multimediali del computer</translation> @@ -3323,7 +3307,6 @@ <translation id="6122875415561139701">Scrittura non consentita su: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">Le seguenti estensioni dipendono da questa estensione:</translation> <translation id="6125479973208104919">Purtroppo devi aggiungere nuovamente il tuo account al dispositivo <ph name="DEVICE_TYPE" />.</translation> -<translation id="612596694132302162">Riattiva l'audio del sito</translation> <translation id="6129691635767514872">I dati selezionati sono stati rimossi da Chrome e dai dispositivi sincronizzati. Il tuo account Google potrebbe avere altre forme di cronologia di navigazione, ad esempio ricerche e attività, di altri servizi Google all'indirizzo <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Commento certificato Netscape</translation> <translation id="6129953537138746214">Spazio</translation> @@ -3526,7 +3509,6 @@ <translation id="6436164536244065364">Visualizza nel Web Store</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - Riproduzione audio in corso</translation> <translation id="6442187272350399447">Strepitoso</translation> -<translation id="6442697326824312960">Sblocca scheda</translation> <translation id="6444070574980481588">Imposta data e ora</translation> <translation id="6445450263907939268">Se non volevi apportare queste modifiche, puoi ripristinare le impostazioni precedenti.</translation> <translation id="6447842834002726250">Cookie</translation> @@ -3729,7 +3711,6 @@ <translation id="6770664076092644100">Verifica tramite NFC</translation> <translation id="6771503742377376720">È un'autorità di certificazione</translation> <translation id="6777817260680419853">Reindirizzamento bloccato</translation> -<translation id="6778959797435875428">Riattiva l'audio dei siti</translation> <translation id="677965093459947883">Molto piccole</translation> <translation id="6780439250949340171">gestire altre impostazioni</translation> <translation id="6781284683813954823">Link del doodle</translation> @@ -4046,7 +4027,6 @@ <translation id="7257666756905341374">Lettura dei dati copiati e incollati</translation> <translation id="7258697411818564379">PIN aggiunto</translation> <translation id="7262004276116528033">Questo servizio di accesso è in hosting su <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Chiudi schede</translation> <translation id="7268659760406822741">Servizi disponibili</translation> <translation id="7270858098575133036">Chiedi conferma quando un sito vuole utilizzare messaggi esclusivi di sistema per accedere a dispositivi MIDI</translation> <translation id="7272674038937250585">Nessuna descrizione fornita</translation> @@ -4234,7 +4214,6 @@ <translation id="7576032389798113292">6 x 4</translation> <translation id="7576690715254076113">Fascicola</translation> <translation id="7576976045740938453">Si è verificato un problema con l'account della modalità demo.</translation> -<translation id="7579149537961810247">Disattiva l'audio dei siti</translation> <translation id="7580671184200851182">Riproduci lo stesso audio su tutti gli altoparlanti (audio mono)</translation> <translation id="7581462281756524039">Uno strumento per la pulizia</translation> <translation id="7582582252461552277">Preferisci questa rete</translation> @@ -4588,7 +4567,6 @@ <translation id="8068253693380742035">Tocca per accedere</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Stampa come immagine</translation> -<translation id="8072988827236813198">Blocca le schede</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Per dati delle app si intende qualsiasi dato salvato nell'app (in base alle impostazioni sviluppatore), inclusi dati come contatti, messaggi e foto.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />I dati di backup non vengono considerati per la quota di spazio di archiviazione di Drive.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Puoi disattivare questo servizio nelle Impostazioni.<ph name="END_PARAGRAPH3" /></translation> @@ -4773,7 +4751,6 @@ <translation id="8368859634510605990">&Apri tutti i Preferiti</translation> <translation id="8371695176452482769">Parla adesso</translation> <translation id="8372369524088641025">Chiave WEP non valida</translation> -<translation id="8373553483208508744">Disattiva audio schede</translation> <translation id="8378714024927312812">Gestito dalla tua organizzazione</translation> <translation id="8379878387931047019">Questo dispositivo non supporta il tipo di token di sicurezza richiesto da questo sito web</translation> <translation id="8382913212082956454">Copia indirizzo &email</translation> @@ -4881,7 +4858,6 @@ <translation id="8546930481464505581">Personalizza la Touch Bar</translation> <translation id="8547013269961688403">Attiva lente d'ingrandimento a schermo intero</translation> <translation id="85486688517848470">Tieni premuto il tasto per la ricerca per modificare la funzione dei tasti della fila superiore</translation> -<translation id="855081842937141170">Blocca scheda</translation> <translation id="8551388862522347954">Licenze</translation> <translation id="8553342806078037065">Gestisci altre persone</translation> <translation id="8554899698005018844">Nessuna lingua</translation> @@ -5195,7 +5171,6 @@ <translation id="9038430547971207796">La prossima volta potrai usare il telefono per sbloccare il tuo dispositivo <ph name="DEVICE_TYPE" />. Disattiva Smart Lock nelle Impostazioni.</translation> <translation id="9038649477754266430">Utilizza un servizio di previsione per velocizzare il caricamento delle pagine</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Disattiva audio schede</translation> <translation id="9040661932550800571">Aggiornare la password per <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">L'accesso ai file locali sul computer è stato disattivato dall'amministratore</translation> <translation id="9042893549633094279">Privacy e sicurezza</translation> @@ -5293,7 +5268,6 @@ <translation id="920045321358709304">Cerca su <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Opzioni di blocco schermo</translation> <translation id="9203398526606335860">&Profiling attivato</translation> -<translation id="9203478404496196495">Riattiva audio scheda</translation> <translation id="9203904171912129171">Seleziona un dispositivo</translation> <translation id="9203962528777363226">L'amministratore di questo dispositivo ha disattivato l'aggiunta di nuovi utenti</translation> <translation id="9213073329713032541">Installazione eseguita correttamente.</translation>
diff --git a/chrome/app/resources/generated_resources_iw.xtb b/chrome/app/resources/generated_resources_iw.xtb index 1b223c6..02cb9f7 100644 --- a/chrome/app/resources/generated_resources_iw.xtb +++ b/chrome/app/resources/generated_resources_iw.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">הקש ESCAPE כדי לדלג (גרסאות לא רשמיות בלבד).</translation> <translation id="1093457606523402488">רשתות גלויות:</translation> <translation id="1094607894174825014">פעולת קריאה או כתיבה התבקשה עם היסט לא חוקי במכשיר: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">בטל השתקת אתרים</translation> <translation id="1097658378307015415">לפני הכניסה לחשבון, היכנס כאורח כדי להפעיל את הרשת <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">תרגם <ph name="LANGUAGE" /> תמיד</translation> <translation id="1108600514891325577">&הפסק</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">חלון גלישה בסתר מאפשר לגלוש בלי לשמור את היסטוריית הגלישה</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> טביעות אצבעות הוגדרו</translation> <translation id="1215411991991485844">נוסף יישום רקע חדש</translation> -<translation id="1216654534877302979">השתק אתרים</translation> <translation id="1216659994753476700">מצטערים, אין לנו אפשרות לגשת לפרופיל שלך. ייתכן שהקבצים והנתונים המאוחסנים במכשיר זה אבדו.<ph name="BR" /> <ph name="BR" /> עליך להגדיר את הפרופיל פעם נוספת.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">אחסן נתונים בחשבון Google Drive</translation> <translation id="1288037062697528143">תאורת הלילה תידלק באופן אוטומטי בשעת השקיעה</translation> <translation id="1288300545283011870">תכונות דיבור</translation> -<translation id="1293177648337752319">בטל את השתקת האתר</translation> <translation id="1293264513303784526">מכשיר עם יציאת USB-C (יציאה שמאלית)</translation> <translation id="1293556467332435079">קבצים</translation> <translation id="1296497012903089238">סוג אישור</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">דף הבית הוא הדף 'כרטיסייה חדשה'</translation> <translation id="1436671784520050284">להמשך ההגדרה</translation> <translation id="1436784010935106834">הוסר</translation> -<translation id="1438632560381091872">ביטול השתקת כרטיסיות</translation> <translation id="1442392616396121389">קידומת לניתוב</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> פריטים נבחרו</translation> <translation id="1444628761356461360">ההגדרה הזו מנוהלת על ידי בעל המכשיר, <ph name="OWNER_EMAIL" />.</translation> @@ -385,7 +381,6 @@ <translation id="1567387640189251553">חוברה מקלדת אחרת מאז שהזנת את הסיסמה בפעם האחרונה. ייתכן שהיא מנסה לתעד את ההקשות שלך.</translation> <translation id="1567750922576943685">אימות הזהות עוזר להגן על המידע האישי</translation> <translation id="1567993339577891801">קונסולת JavaScript</translation> -<translation id="1568067597247500137">השתק את האתר</translation> <translation id="1568323446248056064">פתח את הגדרות המכשיר של התצוגה</translation> <translation id="1572266655485775982">הפעלת Wi-Fi</translation> <translation id="1572585716423026576">הגדרה כטפט</translation> @@ -437,7 +432,6 @@ <translation id="1643072738649235303">חתימת X9.62 ECDSA עם SHA-1</translation> <translation id="1644574205037202324">היסטוריה</translation> <translation id="1645516838734033527">כדי לשמור על הבטיחות של <ph name="DEVICE_TYPE" />, Smart Lock מחייב נעילת מסך בטלפון שלך.</translation> -<translation id="1646102270785326155">כל הקבצים והנתונים המשויכים למשתמש זה יימחקו לצמיתות ברגע שהמשתמש יוסר. 1$ יוכל עדיין להיכנס בהמשך.</translation> <translation id="1646982517418478057">הזן סיסמה כדי להצפין את האישור הזה</translation> <translation id="164814987133974965">משתמש בפיקוח יכול לסייר באינטרנט בהנחייתך. כמנהל של משתמש בפיקוח, אתה יכול <ph name="BEGIN_BOLD" />להתיר או לאסור<ph name="END_BOLD" /> כניסה לאתרים מסוימים, @@ -496,7 +490,6 @@ <translation id="1729533290416704613">הגדרה זו גם קובעת איזה דף מוצג כשאתה מבצע חיפוש מסרגל הכתובות.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />כדי להסיר אפליקציות, נכנסים אל 'הגדרות' > 'חנות Google Play' > 'ניהול העדפות Android' >'אפליקציות' או 'מנהל האפליקציות'. אחר כך מקישים על האפליקציה שרוצים להסיר (ייתכן שיהיה צורך להחליק ימינה או שמאלה כדי למצוא את האפליקציה). לסיום, מקישים על 'הסרת התקנה' או 'השבתה'.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">שולח בקשה...</translation> -<translation id="1732215134274276513">בטל הצמדה של כרטיסיות</translation> <translation id="1733383495376208985">הצפנת נתונים מסונכרנים בעזרת <ph name="BEGIN_LINK" />ביטוי סיסמה אישי לסנכרון<ph name="END_LINK" />. ההצפנה לא כוללת אמצעי תשלום וכתובות מ-Google Pay.</translation> <translation id="1734824808160898225">ייתכן ש-<ph name="PRODUCT_NAME" /> לא יוכל להתעדכן</translation> <translation id="1736419249208073774">מידע נוסף</translation> @@ -548,7 +541,6 @@ <translation id="1807938677607439181">כל הקבצים</translation> <translation id="1809734401532861917">הוספת הסימניות, ההיסטוריה, הסיסמאות והגדרות נוספות שלי אל <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">אין תצוגה מקדימה זמינה</translation> -<translation id="1812631533912615985">בטל הצמדה של כרטיסיות</translation> <translation id="1813278315230285598">שירותים</translation> <translation id="18139523105317219">שם צד EDI</translation> <translation id="1815083418640426271">הדבק כטקסט רגיל</translation> @@ -707,7 +699,6 @@ <translation id="2065405795449409761">Chrome נשלט על-ידי תוכנת בדיקה אוטומטית.</translation> <translation id="2070909990982335904">שמות המתחילים בנקודה שמורים עבור המערכת. בחר שם אחר.</translation> <translation id="2071393345806050157">אין קובץ יומן מקומי.</translation> -<translation id="2074527029802029717">בטל הצמדה של כרטיסייה</translation> <translation id="2075474481720804517">%<ph name="BATTERY_PERCENTAGE" /> סוללה</translation> <translation id="2075959085554270910">הגדרות אלה מאפשרות להפעיל או להשבית את תכונות הנגיעה הקלה וההקשה לגרירה</translation> <translation id="2076269580855484719">הסתר פלאגין זה</translation> @@ -1354,7 +1345,6 @@ <translation id="3045447014237878114">האתר הזה הוריד קבצים מרובים באופן אוטומטי</translation> <translation id="3046910703532196514">דף אינטרנט, שלם</translation> <translation id="304747341537320566">מנועי דיבור</translation> -<translation id="304826556400666995">ביטול השתקת כרטיסיות</translation> <translation id="3053013834507634016">שימוש במפתח אישור </translation> <translation id="3057861065630527966">גבה את התמונות והסרטונים</translation> <translation id="3060379269883947824">הפעלת הקראה</translation> @@ -2340,7 +2330,6 @@ <translation id="4628762811416793313">הגדרת מאגר Linux לא הושלמה. אפשר לנסות שוב.</translation> <translation id="4628948037717959914">תמונה</translation> <translation id="4631887759990505102">אמן</translation> -<translation id="4632483769545853758">ביטול השתקה של כרטיסייה</translation> <translation id="4633003931260532286">כדי להשתמש בתוסף יש צורך ב-"<ph name="IMPORT_NAME" />" בגירסה "<ph name="IMPORT_VERSION" />" לפחות, אך הגירסה המותקנת היא רק "<ph name="INSTALLED_VERSION" />"</translation> <translation id="4634771451598206121">היכנס שוב...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> לא זמין למשתמשים במצב אורח.</translation> @@ -2405,7 +2394,6 @@ <translation id="4736292055110123391">סנכרון הסימניות, הסיסמאות, ההיסטוריה ונתונים נוספים בכל המכשירים שברשותך</translation> <translation id="4737715515457435632">התחבר לרשת</translation> <translation id="473775607612524610">עדכן</translation> -<translation id="474217410105706308">השתק כרטיסייה</translation> <translation id="4742746985488890273">הצמד למדף</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />איך לעדכן אפליקציות<ph name="END_LINK" /></translation> <translation id="4746351372139058112">הודעות</translation> @@ -2630,7 +2618,6 @@ <translation id="5094721898978802975">יצירת קשר עם יישומים מקוריים שמשתפים פעולה</translation> <translation id="5097002363526479830">ההתחברות לרשת נכשלה '<ph name="NAME" />': <ph name="DETAILS" /></translation> <translation id="5101042277149003567">פתח את כל הסימניות</translation> -<translation id="5105855035535475848">הצמד כרטיסיות</translation> <translation id="5108967062857032718">הגדרות - הסר אפליקציות Android</translation> <translation id="5109044022078737958">מיה</translation> <translation id="5111692334209731439">&מנהל הסימניות</translation> @@ -2695,7 +2682,6 @@ <translation id="520621735928254154">שגיאה בייבוא האישור</translation> <translation id="5209320130288484488">לא נמצאו מכשירים</translation> <translation id="5209518306177824490">טביעת אצבע SHA-1</translation> -<translation id="5210365745912300556">סגור כרטיסייה</translation> <translation id="5213481667492808996">שירות הנתונים של '<ph name="NAME" />' מוכן לשימוש</translation> <translation id="5213891612754844763">הצג את ההגדרות של שרת ה-proxy</translation> <translation id="521582610500777512">התצלום נמחק</translation> @@ -2748,7 +2734,6 @@ <translation id="5272654297705279635">הגדרות מותאמות אישית</translation> <translation id="5275352920323889391">כלב</translation> <translation id="5275973617553375938">קבצים ששוחזרו מ-Google Drive</translation> -<translation id="527605719918376753">השתק כרטיסייה</translation> <translation id="527605982717517565">אפשר תמיד JavaScript ב-<ph name="HOST" /></translation> <translation id="5280426389926346830">ליצור קיצור דרך?</translation> <translation id="528208740344463258">צריך להתקין את העדכון הנדרש הזה כדי להוריד אפליקציות Android ולהשתמש בהן. לא יתאפשר לך להשתמש ב-<ph name="DEVICE_TYPE" /> בזמן העדכון. כשההתקנה תסתיים, ה-<ph name="DEVICE_TYPE" /> יופעל מחדש.</translation> @@ -2871,7 +2856,6 @@ <translation id="5449551289610225147">סיסמה לא חוקית</translation> <translation id="5449588825071916739">צור סימניה לכל הכרטיסיות</translation> <translation id="5449716055534515760">סגור ח&לון</translation> -<translation id="5453029940327926427">סגור כרטיסיות</translation> <translation id="5454166040603940656">עם <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">לא חוקי</translation> <translation id="5457459357461771897">קריאה ומחיקה של קובצי תמונות, מוזיקה ומדיה מסוגים נוספים מהמחשב שלך</translation> @@ -3336,7 +3320,6 @@ <translation id="6122875415561139701">פעולת כתיבה אסורה במכשיר: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">התוספים הבאים תלויים בתוסף הזה:</translation> <translation id="6125479973208104919">תצטרך להוסיף את החשבון שלך ב-<ph name="DEVICE_TYPE" /> פעם נוספת.</translation> -<translation id="612596694132302162">בטל את השתקת האתר</translation> <translation id="6129691635767514872">הנתונים שבחרת הוסרו מ-Chrome ומהמכשירים המסונכרנים. ייתכן שבכתובת <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> עדיין יתאפשר לך לגשת לסוגים אחרים של היסטוריית גלישה בחשבון Google, כמו חיפושים ופעילות משירותים אחרים של Google.</translation> <translation id="6129938384427316298">הערה לאישור Netscape</translation> <translation id="6129953537138746214">רווח</translation> @@ -3539,7 +3522,6 @@ <translation id="6436164536244065364">הצג בחנות אינטרנט</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - אודיו מופעל</translation> <translation id="6442187272350399447">גדול!</translation> -<translation id="6442697326824312960">בטל הצמדה של כרטיסייה</translation> <translation id="6444070574980481588">הגדרת תאריך ושעה</translation> <translation id="6445450263907939268">אם לא רצית את השינויים האלו, תוכל לשחזר את ההגדרות הקודמות שלך.</translation> <translation id="6447842834002726250">קובצי Cookie</translation> @@ -3742,7 +3724,6 @@ <translation id="6770664076092644100">אימות באמצעות NFC</translation> <translation id="6771503742377376720">הוא רשות אישורים</translation> <translation id="6777817260680419853">הפניה לכתובת אתר אחרת נחסמה</translation> -<translation id="6778959797435875428">בטל השתקת אתרים</translation> <translation id="677965093459947883">קטן מאוד</translation> <translation id="6780439250949340171">ניהול הגדרות אחרות</translation> <translation id="6781284683813954823">קישור אל ה-Doodle</translation> @@ -4059,7 +4040,6 @@ <translation id="7257666756905341374">קריאת נתונים שאתה מעתיק ומדביק</translation> <translation id="7258697411818564379">הקוד נוסף</translation> <translation id="7262004276116528033">שירות הכניסה הזה מתארח ב-<ph name="SAML_DOMAIN" />.</translation> -<translation id="7268365133021434339">סגור כרטיסיות</translation> <translation id="7268659760406822741">שירותים זמינים</translation> <translation id="7270858098575133036">שאל כשאתר רוצה להשתמש בהודעות בלעדיות של המערכת כדי לגשת להתקני MIDI</translation> <translation id="7272674038937250585">לא סופק תיאור</translation> @@ -4247,7 +4227,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">אסוף</translation> <translation id="7576976045740938453">התרחשה בעיה שקשורה לחשבון מצב ההדגמה.</translation> -<translation id="7579149537961810247">השתק אתרים</translation> <translation id="7580671184200851182">השמע את אותו אודיו מכל הרמקולים (אודיו מונו)</translation> <translation id="7581462281756524039">כלי לניקוי</translation> <translation id="7582582252461552277">העדף רשת זו</translation> @@ -4600,7 +4579,6 @@ <translation id="8068253693380742035">גע כדי להיכנס</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">הדפסה כתמונה</translation> -<translation id="8072988827236813198">הצמד כרטיסיות</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />נתוני אפליקציות הם כל הנתונים הנשמרים באפליקציות (בהתאם להגדרות המפתחים), כולל נתונים כמו אנשי קשר, הודעות ותמונות.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />נתוני הגיבוי אינם תופסים חלק מהמכסה של חשבון הילד/ה שלך ב-Drive.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />אפשר לכבות את השירות הזה ב'הגדרות'.<ph name="END_PARAGRAPH3" /></translation> @@ -4788,7 +4766,6 @@ <translation id="8368859634510605990">&פתח את כל הסימניות</translation> <translation id="8371695176452482769">דבר עכשיו</translation> <translation id="8372369524088641025">מקש WEP גרוע</translation> -<translation id="8373553483208508744">השתק כרטיסיות</translation> <translation id="8378714024927312812">מנוהל על-ידי הארגון</translation> <translation id="8379878387931047019">המכשיר לא תומך במפתח אבטחה מהסוג המבוקש באתר הזה</translation> <translation id="8382913212082956454">העתק &כתובת אימייל</translation> @@ -4896,7 +4873,6 @@ <translation id="8546930481464505581">התאם אישית את סרגל המגע</translation> <translation id="8547013269961688403">הפעלת מגדיל למסך מלא</translation> <translation id="85486688517848470">החזק את מקש החיפוש כדי לשנות את ההתנהגות של מקשי השורה העליונה</translation> -<translation id="855081842937141170">הצמד כרטיסייה</translation> <translation id="8551388862522347954">רישיונות</translation> <translation id="8553342806078037065">נהל אנשים אחרים</translation> <translation id="8554899698005018844">לא הוגדרה שפה</translation> @@ -5211,7 +5187,6 @@ <translation id="9038430547971207796">בפעם הבאה, הטלפון שלך יבטל את הנעילה של <ph name="DEVICE_TYPE" />. בהגדרות אפשר להשבית את Smart Lock.</translation> <translation id="9038649477754266430">השתמש בשירות חיזוי כדי לטעון דפים מהר יותר</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">השתקת כרטיסיות</translation> <translation id="9040661932550800571">האם לעדכן את הסיסמה של <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">הגישה לקבצים מקומיים במחשב שלך מושבתת על-ידי מנהל המערכת</translation> <translation id="9042893549633094279">פרטיות ואבטחה</translation> @@ -5309,7 +5284,6 @@ <translation id="920045321358709304">חפש ב-<ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">אפשרויות נעילת מסך</translation> <translation id="9203398526606335860">&יצירת פרופילים מופעלת</translation> -<translation id="9203478404496196495">בטל השתקת כרטיסייה</translation> <translation id="9203904171912129171">בחירת מכשיר</translation> <translation id="9203962528777363226">מנהל המערכת של מכשיר זה השבית את ההוספה של משתמשים חדשים</translation> <translation id="9213073329713032541">ההתקנה התחילה בהצלחה.</translation>
diff --git a/chrome/app/resources/generated_resources_ja.xtb b/chrome/app/resources/generated_resources_ja.xtb index e718f71..a3370f6 100644 --- a/chrome/app/resources/generated_resources_ja.xtb +++ b/chrome/app/resources/generated_resources_ja.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Esc キーを押すとスキップできます(非公式のビルドのみ)。</translation> <translation id="1093457606523402488">検出されたネットワーク:</translation> <translation id="1094607894174825014">「<ph name="DEVICE_NAME" />」で、無効なオフセットでの読み取りまたは書き込み操作がリクエストされました。</translation> -<translation id="109758035718544977">複数のサイトのミュートを解除</translation> <translation id="1097658378307015415">ログインする前に、ゲスト セッションを開始して <ph name="NETWORK_ID" /> ネットワークを有効にしてください</translation> <translation id="1103523840287552314"><ph name="LANGUAGE" />を常に翻訳</translation> <translation id="1108600514891325577">停止(&S)</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">シークレット ウィンドウを使うと、閲覧履歴を残さずにウェブを閲覧できます</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> 個の指紋を登録済み</translation> <translation id="1215411991991485844">新しいバックグラウンド アプリが追加されました</translation> -<translation id="1216654534877302979">複数のサイトをミュート</translation> <translation id="1216659994753476700">プロフィールにアクセスできません。このデバイスに保存されているファイルやデータが失われている可能性があります。<ph name="BR" /> <ph name="BR" /> プロフィールをもう一度設定する必要があります。<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Google ドライブ アカウントでのデータの保存</translation> <translation id="1288037062697528143">夜間モードは日の入り時刻に自動的にオンになります</translation> <translation id="1288300545283011870">読み上げのプロパティ</translation> -<translation id="1293177648337752319">サイトのミュートを解除</translation> <translation id="1293264513303784526">USB-C デバイス(左側面のポート)</translation> <translation id="1293556467332435079">ファイル</translation> <translation id="1296497012903089238">証明書の種類</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">ホームページは新しいタブのページです</translation> <translation id="1436671784520050284">設定を続行</translation> <translation id="1436784010935106834">削除しました</translation> -<translation id="1438632560381091872">タブのミュートを解除</translation> <translation id="1442392616396121389">ルーティング プレフィックス</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> 個のアイテムを選択しました</translation> <translation id="1444628761356461360">この設定はデバイスの所有者 <ph name="OWNER_EMAIL" /> が管理しています。</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">前回のパスワード入力時以降に別のキーボードが接続されました。キー入力が読み取られる可能性があります。</translation> <translation id="1567750922576943685">本人確認をすることで個人情報を保護できます</translation> <translation id="1567993339577891801">JavaScript コンソール</translation> -<translation id="1568067597247500137">サイトをミュート</translation> <translation id="1568323446248056064">ディスプレイのデバイス設定を開く</translation> <translation id="1572266655485775982">Wi-Fi の有効化</translation> <translation id="1572585716423026576">壁紙に設定</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">X9.62 ECDSA 署名(SHA-1)</translation> <translation id="1644574205037202324">履歴</translation> <translation id="1645516838734033527"><ph name="DEVICE_TYPE" /> を安全に保つため、Smart Lock を使用するにはスマートフォンで画面ロックが設定されていることが要件となります。</translation> -<translation id="1646102270785326155">このユーザーを削除すると、このユーザーに関連付けられているファイルとローカルデータもすべて完全に削除されます。$1 は今後も引き続きログインできます。</translation> <translation id="1646982517418478057">この証明書の暗号化に使用するパスワードを入力してください</translation> <translation id="164814987133974965">監視対象ユーザーは、管理者の案内に沿ってウェブを利用できます。Chrome の監視対象ユーザーの管理者ができることは次のとおりです: 特定のウェブサイトへのアクセスを<ph name="BEGIN_BOLD" />許可または禁止<ph name="END_BOLD" />する @@ -499,7 +493,6 @@ <translation id="1729533290416704613">この拡張機能では、アドレスバーからの検索時に表示されるページも制御されます。</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />アプリを削除するには、まず [設定] > [Google Play ストア] > [Android 設定を管理] > [アプリ] または [アプリケーション管理] に移動して、アンインストールするアプリをタップします(必要であれば左右にスワイプしてアプリを見つけます)。次に、[アンインストール] または [無効にする] をタップします。<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">リクエストを送信しています...</translation> -<translation id="1732215134274276513">タブの固定を解除</translation> <translation id="1733383495376208985">同期データを<ph name="BEGIN_LINK" />同期パスフレーズ<ph name="END_LINK" />で暗号化します。なお、Google Pay のお支払い方法と住所はこれには含まれません。</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> を最新の状態に維持できない場合があります</translation> <translation id="1736419249208073774">詳しく見る</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">すべてのファイル</translation> <translation id="1809734401532861917">自分のブックマーク、履歴、パスワード、その他の設定を <ph name="USER_EMAIL_ADDRESS" /> に追加します</translation> <translation id="1810764548349082891">プレビュー機能はご利用いただけません</translation> -<translation id="1812631533912615985">タブの固定を解除</translation> <translation id="1813278315230285598">サービス</translation> <translation id="18139523105317219">EDI パーティ名</translation> <translation id="1815083418640426271">プレーン テキストとして貼り付ける</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chrome は自動テスト ソフトウェアによって制御されています。</translation> <translation id="2070909990982335904">ドットで始まる名前はシステム専用です。別の名前を指定してください。</translation> <translation id="2071393345806050157">ローカルのログ ファイルがありません。</translation> -<translation id="2074527029802029717">タブの固定を解除</translation> <translation id="2075474481720804517">バッテリー残量: <ph name="BATTERY_PERCENTAGE" />%</translation> <translation id="2075959085554270910">タップによるクリックとタップによるドラッグを有効化または無効化します</translation> <translation id="2076269580855484719">このプラグインを表示しない</translation> @@ -1352,7 +1343,6 @@ <translation id="3045447014237878114">このサイトで複数のファイルが自動的にダウンロードされました</translation> <translation id="3046910703532196514">ウェブページ、完全</translation> <translation id="304747341537320566">読み上げエンジン</translation> -<translation id="304826556400666995">タブのミュートを解除</translation> <translation id="3053013834507634016">証明書キーの用途</translation> <translation id="3057861065630527966">写真や動画をバックアップします</translation> <translation id="3060379269883947824">「選択して読み上げ」を有効にする</translation> @@ -1544,7 +1534,7 @@ <translation id="337920581046691015"><ph name="PRODUCT_NAME" /> がインストールされます。</translation> <translation id="3380365263193509176">不明なエラー</translation> <translation id="3382073616108123819">このデバイスの端末識別子を特定できませんでした。</translation> -<translation id="3382200254148930874">管理ツールを停止しています...</translation> +<translation id="3382200254148930874">管理機能を停止しています...</translation> <translation id="338583716107319301">セパレータ</translation> <translation id="3389312115541230716">タスクバーで <ph name="SMALL_PRODUCT_LOGO" /> アイコンを右クリックします</translation> <translation id="3396800784455899911">[同意して続行] をクリックすると、これらの Google サービスに関する上記の処理内容に同意したことになります。</translation> @@ -1869,7 +1859,7 @@ <translation id="3839516600093027468"><ph name="HOST" /> によるクリップボードへのアクセスを常にブロックする</translation> <translation id="3842552989725514455">Serif フォント</translation> <translation id="3846116211488856547">ウェブサイト、Android アプリなどの開発に役立つツールをご利用ください。Linux をインストールする際には <ph name="DOWNLOAD_SIZE" /> のデータがダウンロードされます。</translation> -<translation id="3850262920366203352">管理ツールを設定しています...</translation> +<translation id="3850262920366203352">管理機能を設定しています...</translation> <translation id="385051799172605136">戻る</translation> <translation id="3851428669031642514">安全でないスクリプトを読み込む</translation> <translation id="3854599674806204102">オプションを選択してください</translation> @@ -2335,7 +2325,6 @@ <translation id="4628762811416793313">Linux コンテナの設定を完了できませんでした。もう一度お試しください。</translation> <translation id="4628948037717959914">写真</translation> <translation id="4631887759990505102">アーティスト</translation> -<translation id="4632483769545853758">タブのミュートを解除</translation> <translation id="4633003931260532286">拡張機能には「<ph name="IMPORT_NAME" />」のバージョン「<ph name="IMPORT_VERSION" />」以上が必要ですが、インストールされているのはバージョン「<ph name="INSTALLED_VERSION" />」のみです</translation> <translation id="4634771451598206121">もう一度ログインする...</translation> <translation id="4635398712689569051">ゲストユーザーは <ph name="PAGE_NAME" /> を利用できません。</translation> @@ -2399,7 +2388,6 @@ <translation id="4735803855089279419">この端末の端末識別子を特定できませんでした。</translation> <translation id="4737715515457435632">ネットワークに接続してください</translation> <translation id="473775607612524610">更新</translation> -<translation id="474217410105706308">タブをミュート</translation> <translation id="4742746985488890273">シェルフに固定</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />アプリケーションの更新方法を確認<ph name="END_LINK" /></translation> <translation id="4746351372139058112">メッセージ</translation> @@ -2624,7 +2612,6 @@ <translation id="5094721898978802975">連携するネイティブ アプリケーションと通信</translation> <translation id="5097002363526479830">ネットワーク「<ph name="NAME" />」に接続できませんでした: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">すべてのブックマークを開く</translation> -<translation id="5105855035535475848">複数のタブを固定</translation> <translation id="5108967062857032718">設定 - Android アプリの削除</translation> <translation id="5109044022078737958">ミア</translation> <translation id="5111692334209731439">ブックマーク マネージャ(&B)</translation> @@ -2689,7 +2676,6 @@ <translation id="520621735928254154">証明書のインポート エラー</translation> <translation id="5209320130288484488">デバイスが見つかりませんでした</translation> <translation id="5209518306177824490">SHA-1 指紋</translation> -<translation id="5210365745912300556">タブを閉じる</translation> <translation id="5213481667492808996">「<ph name="NAME" />」データサービスを使用できるようになりました</translation> <translation id="5213891612754844763">プロキシ設定を表示</translation> <translation id="521582610500777512">写真を破棄しました</translation> @@ -2740,7 +2726,6 @@ <translation id="5270167208902136840">その他の <ph name="NUMBER_OF_MORE_APPS" /> 個のアプリを表示</translation> <translation id="5275352920323889391">犬</translation> <translation id="5275973617553375938">Google ドライブから復元されたファイル</translation> -<translation id="527605719918376753">タブをミュート</translation> <translation id="527605982717517565"><ph name="HOST" /> の Javascript を常に許可する</translation> <translation id="5280426389926346830">ショートカットを作成しますか?</translation> <translation id="528208740344463258">Android アプリをダウンロードして使用するには、まずこの必須のアップデートをインストールする必要があります。<ph name="DEVICE_TYPE" /> の更新中、ご利用いただくことはできません。インストールが完了すると、<ph name="DEVICE_TYPE" /> は再起動されます。</translation> @@ -2863,7 +2848,6 @@ <translation id="5449551289610225147">パスワードが無効です</translation> <translation id="5449588825071916739">すべてのタブをブックマークに追加する</translation> <translation id="5449716055534515760">ウィンドウを閉じる(&D)</translation> -<translation id="5453029940327926427">複数のタブを閉じる</translation> <translation id="5454166040603940656">- <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">無効</translation> <translation id="5457459357461771897">パソコンからの写真、音楽、その他のメディアの読み取りと削除</translation> @@ -3328,7 +3312,6 @@ <translation id="6122875415561139701">「<ph name="DEVICE_NAME" />」での書き込み操作は許可されていません。</translation> <translation id="6124650939968185064">次の拡張機能は、この拡張機能に依存しています:</translation> <translation id="6125479973208104919">アカウントをもう一度この <ph name="DEVICE_TYPE" /> に追加する必要があります。</translation> -<translation id="612596694132302162">サイトのミュートを解除</translation> <translation id="6129691635767514872">選択したデータが Chrome から削除され、同期された端末からも削除されました。他の Google サービスでの検索や操作など、Google アカウントの他の形式の閲覧履歴が <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> に残ることがあります。</translation> <translation id="6129938384427316298">Netscape 証明書コメント</translation> <translation id="6129953537138746214">Space</translation> @@ -3474,7 +3457,7 @@ <translation id="6351063337294363751">このメニューで閲覧データを削除できます</translation> <translation id="6352773953037195952">最も高い</translation> <translation id="6354918092619878358">SECG 楕円曲線 secp256r1(別名 ANSI X9.62 prime256v1、NIST P-256)</translation> -<translation id="635609604405270300">端末の電源を切らないでください</translation> +<translation id="635609604405270300">デバイスの電源を切らないでください</translation> <translation id="6356138805250111037">ユーザーがブラウザに入力した内容を Google に送信し、高度なスペルチェックを行います</translation> <translation id="63566973648609420">パスフレーズを知っているユーザーだけが暗号化データを読み取ることができます。パスフレーズが Google に送信されたり Google で保存されたりすることはありません。パスフレーズを忘れた場合や、この設定を変更する場合は、<ph name="BEGIN_LINK" />同期をリセット<ph name="END_LINK" />する必要があります。</translation> <translation id="6357619544108132570"><ph name="SHORT_PRODUCT_NAME" /> ファミリーへようこそ。これは新しいタイプのパソコンです。</translation> @@ -3531,7 +3514,6 @@ <translation id="6436164536244065364">ウェブストアで見る</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - オーディオ再生中です</translation> <translation id="6442187272350399447">ビックリ</translation> -<translation id="6442697326824312960">タブの固定を解除</translation> <translation id="6444070574980481588">日時の設定</translation> <translation id="6445450263907939268">この変更を受け入れない場合は、以前の設定を復元できます。</translation> <translation id="6447842834002726250">Cookie</translation> @@ -3734,7 +3716,6 @@ <translation id="6770664076092644100">NFC を使って確認</translation> <translation id="6771503742377376720">認証局である</translation> <translation id="6777817260680419853">リダイレクトがブロックされました</translation> -<translation id="6778959797435875428">複数のサイトのミュートを解除</translation> <translation id="677965093459947883">極小</translation> <translation id="6780439250949340171">その他の設定を管理する</translation> <translation id="6781284683813954823">Doodle リンク</translation> @@ -3784,7 +3765,7 @@ <translation id="6841186874966388268">エラー</translation> <translation id="6843423766595476978">OK Google の設定が完了しました</translation> <translation id="6845038076637626672">最大化して開く</translation> -<translation id="6848388270925200958">現在、この端末でのみ使用できるカードがいくつかあります</translation> +<translation id="6848388270925200958">現在、このデバイスでのみ使用できるカードがいくつかあります</translation> <translation id="6851497530878285708">アプリは有効です</translation> <translation id="6853388645642883916">アップデータのスリープ中</translation> <translation id="68541483639528434">他のタブをすべて閉じる</translation> @@ -4041,7 +4022,7 @@ <translation id="7253521419891527137">詳細(&L)</translation> <translation id="7254554697254365959">このページを翻訳できませんでした。</translation> <translation id="7254951428499890870">「<ph name="APP_NAME" />」を診断モードで起動してもよろしいですか?</translation> -<translation id="7255002516883565667">現在、この端末でのみ使用できるカードが 1 つあります</translation> +<translation id="7255002516883565667">現在、このデバイスでのみ使用できるカードが 1 つあります</translation> <translation id="7255220508626648026"><ph name="ROUTETITLE" /> をキャスト中</translation> <translation id="7255935316994522020">適用</translation> <translation id="7256069762010468647">サイトでカメラが使用されています</translation> @@ -4051,7 +4032,6 @@ <translation id="7257666756905341374">コピー&ペーストするデータの読み取り</translation> <translation id="7258697411818564379">PIN を追加しました</translation> <translation id="7262004276116528033">このログイン サービスは <ph name="SAML_DOMAIN" /> でホストされています</translation> -<translation id="7268365133021434339">複数のタブを閉じる</translation> <translation id="7268659760406822741">利用可能なサービス</translation> <translation id="7270858098575133036">サイトがシステム エクスクルーシブ メッセージを使用して MIDI デバイスにアクセスする際に確認する</translation> <translation id="7272674038937250585">説明が提供されていません</translation> @@ -4242,7 +4222,6 @@ <translation id="7576032389798113292">6×4</translation> <translation id="7576690715254076113">部単位で印刷</translation> <translation id="7576976045740938453">デモモード アカウントで問題が発生しました。</translation> -<translation id="7579149537961810247">複数のサイトをミュート</translation> <translation id="7580671184200851182">すべてのスピーカーで同じオーディオを再生(モノラル オーディオ)</translation> <translation id="7581462281756524039">クリーンアップ ツール</translation> <translation id="7582582252461552277">このネットワークを優先する</translation> @@ -4596,7 +4575,6 @@ <translation id="8068253693380742035">タップしてログイン</translation> <translation id="8069615408251337349">Google クラウド プリント</translation> <translation id="8071432093239591881">画像として印刷する</translation> -<translation id="8072988827236813198">複数のタブを固定</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />アプリのデータとは、(デベロッパーの設定に基づき)アプリで保存されたあらゆるデータを指します。これには連絡先、メッセージ、写真などのデータも含まれます。<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />バックアップ データは、お子様の Google ドライブの保存容量にはカウントされません。<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />このサービスは [設定] でオフにできます。<ph name="END_PARAGRAPH3" /></translation> @@ -4782,7 +4760,6 @@ <translation id="8368859634510605990">すべてのブックマークを開く(&O)</translation> <translation id="8371695176452482769">お話しください</translation> <translation id="8372369524088641025">WEP キーが正しくありません</translation> -<translation id="8373553483208508744">タブをミュート</translation> <translation id="8378714024927312812">組織によって管理されています</translation> <translation id="8379878387931047019">この端末では、このウェブサイトからリクエストされているセキュリティ キーのタイプはサポートされていません。</translation> <translation id="8382913212082956454">メール アドレスをコピー(&E)</translation> @@ -4890,7 +4867,6 @@ <translation id="8546930481464505581">Touch Bar をカスタマイズ</translation> <translation id="8547013269961688403">拡大鏡(全画面)を有効にする</translation> <translation id="85486688517848470">キーボードの最上段にあるキーの動作を切り替えるには、検索キーを押したままにします</translation> -<translation id="855081842937141170">タブを固定</translation> <translation id="8551388862522347954">ライセンス</translation> <translation id="8553342806078037065">他のユーザーを管理</translation> <translation id="8554899698005018844">言語設定なし</translation> @@ -5204,7 +5180,6 @@ <translation id="9038430547971207796">次回から、スマートフォンで <ph name="DEVICE_TYPE" /> のロックを解除できます。Smart Lock を無効にするには [設定] で指定します。</translation> <translation id="9038649477754266430">予測サービスを使用してページをより迅速に読み込む</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">タブをミュート</translation> <translation id="9040661932550800571"><ph name="ORIGIN" /> のパスワードを更新しますか?</translation> <translation id="9041692268811217999">パソコンのローカル ファイルへのアクセスは管理者によって無効にされています</translation> <translation id="9042893549633094279">プライバシーとセキュリティ</translation> @@ -5302,7 +5277,6 @@ <translation id="920045321358709304"><ph name="SEARCH_ENGINE" /> で検索</translation> <translation id="9201220332032049474">画面ロックの種類</translation> <translation id="9203398526606335860">プロファイル記録の開始(&P)</translation> -<translation id="9203478404496196495">タブのミュートを解除</translation> <translation id="9203904171912129171">端末を選択</translation> <translation id="9203962528777363226">このデバイスの管理者は新規ユーザーの追加を無効にしています</translation> <translation id="9213073329713032541">インストールを開始しました。</translation>
diff --git a/chrome/app/resources/generated_resources_kn.xtb b/chrome/app/resources/generated_resources_kn.xtb index 2e50bd5..0699138 100644 --- a/chrome/app/resources/generated_resources_kn.xtb +++ b/chrome/app/resources/generated_resources_kn.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">ಸ್ಕಿಪ್ ಮಾಡಲು ESCAPE ಅನ್ನು ಒತ್ತಿರಿ (ಅಧಿಕೃತವಲ್ಲದ ಬಿಲ್ಡ್ಗಳಿಗೆ ಮಾತ್ರ).</translation> <translation id="1093457606523402488">ಗೋಚರಿಸುವ ನೆಟ್ವರ್ಕ್ಗಳು:</translation> <translation id="1094607894174825014">ಇದರಲ್ಲಿ ಅಮಾನ್ಯವಾದ ಆಫ್ಸೆಟ್ ಜೊತೆಗೆ ಓದುವ ಅಥವಾ ಬರೆಯುವ ಕಾರ್ಯಾಚರಣೆಯನ್ನು ವಿನಂತಿಸಲಾಗಿದೆ: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">ಸೈಟ್ಗಳನ್ನು ಅನ್ಮ್ಯೂಟ್ ಮಾಡಿ</translation> <translation id="1097658378307015415">ಸೈನ್ ಇನ್ ಮಾಡುವ ಮುನ್ನ, <ph name="NETWORK_ID" /> ನೆಟ್ವರ್ಕ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲು ಅತಿಥಿಯಾಗಿ ಪ್ರವೇಶಿಸಿ</translation> <translation id="1103523840287552314">ಯಾವಾಗಲೂ ಅನುವಾದಿಸಿ <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&ನಿಲ್ಲಿಸು</translation> @@ -152,7 +151,6 @@ <translation id="1211364473545090084">ಅದೃಶ್ಯ ವಿಂಡೋ ಮೂಲಕ ನಿಮ್ಮ ಬ್ರೌಸಿಂಗ್ ಇತಿಹಾಸವನ್ನು ಉಳಿಸದೆಯೇ ವೆಬ್ ಬಳಸಿ</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> ಬೆರಳಚ್ಚುಗಳನ್ನು ಹೊಂದಿಸಲಾಗಿದೆ</translation> <translation id="1215411991991485844">ಹೊಸ ಹಿನ್ನೆಲೆ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಸೇರಿಸಲಾಗಿದೆ</translation> -<translation id="1216654534877302979">ಸೈಟ್ಗಳನ್ನು ಮ್ಯೂಟ್ ಮಾಡಿ</translation> <translation id="1216659994753476700">ನಮ್ಮನ್ನು ಕ್ಷಮಿಸಿ. ನಿಮ್ಮ ಪ್ರೊಫೈಲ್ ಪ್ರವೇಶಿಸಲು ನಮಗೆ ಸಾಧ್ಯವಿಲ್ಲ. ಈ ಸಾಧನದಲ್ಲಿ ಸಂಗ್ರಹಿಸಿದ ಫೈಲ್ಗಳು ಮತ್ತು ಡೇಟಾ ಕಳೆದು ಹೋಗಿರಬಹುದು.<ph name="BR" /> <ph name="BR" /> ನೀವು ಮತ್ತೆ ನಿಮ್ಮ ಪ್ರೊಫೈಲ್ ಅನ್ನು ಹೊಂದಿಸಬೇಕಾಗುತ್ತದೆ.<ph name="BR" /> @@ -202,7 +200,6 @@ <translation id="1285484354230578868">ಡೇಟಾವನ್ನು ನಿಮ್ಮ Google ಡ್ರೈವ್ ಖಾತೆಯಲ್ಲಿ ಸಂಗ್ರಹಿಸಿ</translation> <translation id="1288037062697528143">ನೈಟ್ ಲೈಟ್ ಸೂರ್ಯಾಸ್ತದ ಸಮಯದಲ್ಲಿ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಆನ್ ಆಗುತ್ತದೆ</translation> <translation id="1288300545283011870">ಧ್ವನಿ ಗುಣಲಕ್ಷಣಗಳು</translation> -<translation id="1293177648337752319">ಸೈಟ್ ಅನ್ನು ಅನ್ಮ್ಯೂಟ್ ಮಾಡಿ</translation> <translation id="1293264513303784526">USB-C ಸಾಧನ (ಎಡ ಪೋರ್ಟ್)</translation> <translation id="1293556467332435079">ಫೈಲ್ಗಳು</translation> <translation id="1296497012903089238">ಪ್ರಮಾಣಪತ್ರದ ಪ್ರಕಾರ</translation> @@ -301,7 +298,6 @@ <translation id="1434886155212424586">ಮುಖಪುಟವು ಹೊಸ ಟ್ಯಾಬ್ ಪುಟವಾಗಿದೆ</translation> <translation id="1436671784520050284">ಸೆಟಪ್ ಮುಂದುವರಿಸಿ</translation> <translation id="1436784010935106834">ತೆಗೆದುಹಾಕಲಾಗಿದೆ</translation> -<translation id="1438632560381091872">ಟ್ಯಾಬ್ಗಳನ್ನು ಅನ್ಮ್ಯೂಟ್ ಮಾಡಿ</translation> <translation id="1442392616396121389">ರೂಟಿಂಗ್ ಪೂರ್ವಪ್ರತ್ಯಯ</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ</translation> <translation id="1444628761356461360">ಈ ಸೆಟ್ಟಿಂಗ್ ಅನ್ನು ಸಾಧನದ ಮಾಲೀಕರಿಂದ ನಿರ್ವಹಿಸಿಲಾಗುತ್ತದೆ, <ph name="OWNER_EMAIL" />.</translation> @@ -385,7 +381,6 @@ <translation id="1567387640189251553">ನೀವು ಕೊನೆಯ ಬಾರಿ ಪಾಸ್ವರ್ಡ್ ನಮೂದಿಸುವಾಗ ಇದ್ದ ಕೀಬೋರ್ಡ್ಗಿಂತ ಇದು ಭಿನ್ನವಾಗಿದೆ. ನಿಮ್ಮ ಕೀಸ್ಟ್ರೋಕ್ಗಳನ್ನು ಕಳವು ಮಾಡಲು ಇದು ಪ್ರಯತ್ನಿಸುತ್ತಿರಬಹುದು.</translation> <translation id="1567750922576943685">ನಿಮ್ಮ ಗುರುತನ್ನು ಪರಿಶೀಲಿಸುವುದರಿಂದ ನಿಮ್ಮ ವೈಯಕ್ತಿಕ ಮಾಹಿತಿಯನ್ನು ರಕ್ಷಿಸಲು ಸಹಾಯವಾಗುತ್ತದೆ</translation> <translation id="1567993339577891801">JavaScript ಕನ್ಸೋಲ್</translation> -<translation id="1568067597247500137">ಸೈಟ್ ಅನ್ನು ಮ್ಯೂಟ್ ಮಾಡಿ</translation> <translation id="1568323446248056064">ಪ್ರದರ್ಶನ ಸಾಧನ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ತೆರೆಯಿರಿ</translation> <translation id="1572266655485775982">ವೈ-ಫೈ ಸಕ್ರಿಯ</translation> <translation id="1572585716423026576">ವಾಲ್ಪೇಪರ್ ಆಗಿ ಹೊಂದಿಸಿ</translation> @@ -437,7 +432,6 @@ <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="1646982517418478057">ಈ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಎನ್ಕ್ರಿಪ್ಟ್ ಮಾಡಲು ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ನಮೂದಿಸಿ</translation> <translation id="164814987133974965">ಮೇಲ್ವಿಚಾರಕ ಬಳಕೆದಾರರು ನಿಮ್ಮ ಮಾರ್ಗದರ್ಶನದೊಂದಿಗೆ ವೆಬ್ ಅನ್ನು ಎಕ್ಸ್ಪ್ಲೋರ್ ಮಾಡಬಹುದು. ಮೇಲ್ವಿಚಾರಣೆಯ ಬಳಕೆದಾರರ ನಿರ್ವಾಹಕರಂತೆ ನೀವು ಕೆಲವು ವೆಬ್ಸೈಟ್ಗಳನ್ನು <ph name="BEGIN_BOLD" />ಅನುಮತಿಸಬಹುದು ಅಥವಾ ನಿಷೇಧಿಸಬಹುದು<ph name="END_BOLD" />, @@ -496,7 +490,6 @@ <translation id="1729533290416704613">ಓಮ್ನಿಬಾಕ್ಸ್ನಿಂದ ನೀವು ಹುಡುಕಾಟ ನಡೆಸಿದಾಗ ತೋರಿಸಬೇಕಾದ ಪುಟವನ್ನು ಕೂಡಾ ಇದು ನಿಯಂತ್ರಿಸುತ್ತದೆ.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />ಆ್ಯಪ್ಗಳನ್ನು ತೆಗೆದುಹಾಕಲು, ಸೆಟ್ಟಿಂಗ್ಗಳು > Google Play ಸ್ಟೋರ್ > Android ಆದ್ಯತೆಗಳನ್ನು ನಿರ್ವಹಿಸಿ > ಆ್ಯಪ್ಗಳು ಅಥವಾ ಆ್ಯಪ್ ನಿರ್ವಾಹಕ ಆಯ್ಕೆಗೆ ಹೋಗಿ. ನಂತರ ನೀವು ಅನ್ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ಬಯಸುವ ಆ್ಯಪ್ ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ (ನೀವು ಆ್ಯಪ್ ಅನ್ನು ಹುಡುಕಲು ಎಡಕ್ಕೆ ಅಥವಾ ಬಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡುವ ಅಗತ್ಯವಿರಬಹುದು). ನಂತರ ಅನ್ಇನ್ಸ್ಟಾಲ್ ಅಥವಾ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ ಆಯ್ಕೆಯನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">ವಿನಂತಿಯನ್ನು ಕಳುಹಿಸಲಾಗುತ್ತಿದೆ...</translation> -<translation id="1732215134274276513">ಅನ್ಪಿನ್ ಟ್ಯಾಬ್ಗಳು</translation> <translation id="1733383495376208985">ನಿಮ್ಮ ಸ್ವಂತ <ph name="BEGIN_LINK" />ಸಿಂಕ್ ಪಾಸ್ಫ್ರೇಸ್<ph name="END_LINK" /> ಬಳಸಿಕೊಂಡು ಸಿಂಕ್ ಮಾಡಲಾದ ಡೇಟಾವನ್ನು ಎನ್ಕ್ರಿಪ್ಟ್ ಮಾಡಿ. ಇದು Google Pay ನಿಂದ ಪಾವತಿ ವಿಧಾನಗಳು ಮತ್ತು ವಿಳಾಸಗಳನ್ನು ಒಳಗೊಂಡಿರುವುದಿಲ್ಲ.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> ತಾನಾಗಿಯೇ ಅಪ್ಡೇಟ್ ಆಗಲು ಸಾಧ್ಯವಾಗದಿರಬಹುದು</translation> <translation id="1736419249208073774">ಎಕ್ಸ್ಪ್ಲೋರ್ ಮಾಡಿ</translation> @@ -548,7 +541,6 @@ <translation id="1807938677607439181">ಎಲ್ಲ ಫೈಲ್ಗಳು</translation> <translation id="1809734401532861917"><ph name="USER_EMAIL_ADDRESS" /> ಗೆ ನನ್ನ ಬುಕ್ಮಾರ್ಕ್ಗಳು, ಇತಿಹಾಸ, ಪಾಸ್ವರ್ಡ್ಗಳು ಮತ್ತು ಇತರ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಸೇರಿಸಿ.</translation> <translation id="1810764548349082891">ಯಾವುದೇ ಪೂರ್ವವೀಕ್ಷಣೆ ಲಭ್ಯವಿಲ್ಲ</translation> -<translation id="1812631533912615985">ಅನ್ಪಿನ್ ಟ್ಯಾಬ್ಗಳು</translation> <translation id="1813278315230285598">ಸೇವೆಗಳು</translation> <translation id="18139523105317219">EDI ಪಾರ್ಟಿ ಹೆಸರು</translation> <translation id="1815083418640426271">ಸಾದಾ ಪಠ್ಯದಂತೆ ಅಂಟಿಸಿ</translation> @@ -707,7 +699,6 @@ <translation id="2065405795449409761">Chrome ಅನ್ನು ಸ್ವಯಂಚಾಲಿತ ಪರೀಕ್ಷೆಯ ಸಾಫ್ಟ್ವೇರ್ ನಿಯಂತ್ರಿಸುತ್ತಿದೆ.</translation> <translation id="2070909990982335904">ಡಾಟ್ನೊಂದಿಗೆ ಪ್ರಾರಂಭವಾಗುವ ಹೆಸರುಗಳನ್ನು ಸಿಸ್ಟಂಗಾಗಿ ಕಾಯ್ದಿರಿಸಲಾಗಿದೆ. ದಯವಿಟ್ಟು ಇನ್ನೊಂದು ಹೆಸರನ್ನು ಆಯ್ಕೆಮಾಡಿ.</translation> <translation id="2071393345806050157">ಯಾವುದೇ ಸ್ಥಳೀಯ ಲಾಗ್ ಫೈಲ್ ಇಲ್ಲ.</translation> -<translation id="2074527029802029717">ಅನ್ಪಿನ್ ಟ್ಯಾಬ್</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% ಬ್ಯಾಟರಿ</translation> <translation id="2075959085554270910">ಕ್ಲಿಕ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಎಳೆಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲು/ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ</translation> <translation id="2076269580855484719">ಈ ಪ್ಲಗ್ಇನ್ ಅನ್ನು ಮರೆಮಾಡು</translation> @@ -1348,7 +1339,6 @@ <translation id="3045447014237878114">ಈ ಸೈಟ್ ಬಹು ಫೈಲ್ಗಳನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಡೌನ್ಲೋಡ್ ಮಾಡಿದೆ</translation> <translation id="3046910703532196514">ವೆಬ್ಪುಟ, ಪೂರ್ಣಗೊಳಿಸಿ</translation> <translation id="304747341537320566">ಧ್ವನಿ ಎಂಜಿನ್ಗಳು</translation> -<translation id="304826556400666995">ಟ್ಯಾಬ್ಗಳನ್ನು ಅನ್ಮ್ಯೂಟ್ ಮಾಡಿ</translation> <translation id="3053013834507634016">ಪ್ರಮಾಣಪತ್ರ ಕೀಲಿ ಬಳಕೆ</translation> <translation id="3057861065630527966">ನಿಮ್ಮ ಫೋಟೋಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳನ್ನು ಬ್ಯಾಕಪ್ ಮಾಡಿ</translation> <translation id="3060379269883947824">ಆಯ್ಕೆಮಾಡಿ ಮತ್ತು ಆಲಿಸಿಯನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ</translation> @@ -2331,7 +2321,6 @@ <translation id="4628762811416793313">Linux ಕಂಟೇನರ್ ಸೆಟಪ್ ಪೂರ್ಣವಾಗಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ.</translation> <translation id="4628948037717959914">ಫೋಟೋ</translation> <translation id="4631887759990505102">ಕಲೆಗಾರ</translation> -<translation id="4632483769545853758">ಟ್ಯಾಬ್ ಅನ್ಮ್ಯೂಟ್ ಮಾಡಿ</translation> <translation id="4633003931260532286">ವಿಸ್ತರಣೆಗೆ "<ph name="IMPORT_NAME" />" ನ ಕನಿಷ್ಠ "<ph name="IMPORT_VERSION" />" ಆವೃತ್ತಿಯ ಅಗತ್ಯವಿದೆ, ಆದರೆ "<ph name="INSTALLED_VERSION" />" ಆವೃತ್ತಿಯನ್ನು ಮಾತ್ರ ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾಗಿದೆ</translation> <translation id="4634771451598206121">ಪುನಃ ಸೈನ್ ಇನ್ ಮಾಡಿ...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> ಅತಿಥಿ ಬಳಕೆದಾರರಿಗೆ ಲಭ್ಯವಿಲ್ಲ.</translation> @@ -2395,7 +2384,6 @@ <translation id="4735803855089279419">ಈ ಸಾಧನಕ್ಕಾಗಿ ಸಾಧನದ ಗುರುತುಗಳನ್ನು ನಿರ್ಧರಿಸಲು ಸಿಸ್ಟಂ ವಿಫಲವಾಗಿದೆ.</translation> <translation id="4737715515457435632">ದಯವಿಟ್ಟು ನೆಟ್ವರ್ಕ್ಗೆ ಸಂಪರ್ಕಿಸಿ</translation> <translation id="473775607612524610">ಅಪ್ಡೇಟ್</translation> -<translation id="474217410105706308">ಟ್ಯಾಬ್ ಮ್ಯೂಟ್ ಮಾಡಿ</translation> <translation id="4742746985488890273">ಶೆಲ್ಫ್ಗೆ ಪಿನ್ ಮಾಡು</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡುವುದು ಹೇಗೆ ಎಂದು ತಿಳಿಯಿರಿ<ph name="END_LINK" /></translation> <translation id="4746351372139058112">ಸಂದೇಶಗಳು</translation> @@ -2621,7 +2609,6 @@ <translation id="5094721898978802975">ಸಹಕರಿಸುವ ಸ್ಥಳೀಯ ಅಪ್ಲಿಕೇಶನ್ಗಳೊಂದಿಗೆ ಸಂವಹಿಸಿ</translation> <translation id="5097002363526479830">'<ph name="NAME" />' ನೆಟ್ವರ್ಕ್ಗೆ ಸಂಪರ್ಕಿಸಲು ವಿಫಲವಾಗಿದೆ: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">ಎಲ್ಲಾ ಬುಕ್ಮಾರ್ಕ್ಗಳನ್ನು ತೆರೆಯಿರಿ</translation> -<translation id="5105855035535475848">ಪಿನ್ ಟ್ಯಾಬ್ಗಳು</translation> <translation id="5108967062857032718">ಸೆಟ್ಟಿಂಗ್ಗಳು - Android ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ತೆಗೆದುಹಾಕಿ</translation> <translation id="5109044022078737958">ಮಿಯಾ</translation> <translation id="5111692334209731439">&ಬುಕ್ಮಾರ್ಕ್ ವ್ಯವಸ್ಥಾಪಕ</translation> @@ -2686,7 +2673,6 @@ <translation id="520621735928254154">ಪ್ರಮಾಣಪತ್ರದ ಆಮದು ದೋಷ</translation> <translation id="5209320130288484488">ಯಾವ ಸಾಧನಗಳೂ ಕಂಡುಬಂದಿಲ್ಲ</translation> <translation id="5209518306177824490">SHA-1 ಬೆರಳಚ್ಚು</translation> -<translation id="5210365745912300556">ಟ್ಯಾಬ್ ಅನ್ನು ಮುಚ್ಚಿ</translation> <translation id="5213481667492808996">ನಿಮ್ಮ '<ph name="NAME" />' ಡೇಟಾ ಸೇವೆಯು ಬಳಕೆಗೆ ಸಿದ್ಧವಾಗಿದೆ</translation> <translation id="5213891612754844763">ಪ್ರಾಕ್ಸಿ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ತೋರಿಸಿ</translation> <translation id="521582610500777512">ಫೋಟೋವನ್ನು ತ್ಯಜಿಸಲಾಗಿದೆ</translation> @@ -2739,7 +2725,6 @@ <translation id="5270167208902136840">ಇನ್ನೂ <ph name="NUMBER_OF_MORE_APPS" /> ಆ್ಯಪ್ಗಳನ್ನು ತೋರಿಸಿ</translation> <translation id="5275352920323889391">ನಾಯಿ</translation> <translation id="5275973617553375938">Google ಡ್ರೈವ್ನಿಂದ ಮರುಪಡೆಯಲಾದ ಫೈಲ್ಗಳು</translation> -<translation id="527605719918376753">ಟ್ಯಾಬ್ ಮ್ಯೂಟ್ ಮಾಡಿ</translation> <translation id="527605982717517565"><ph name="HOST" /> ನಲ್ಲಿ JavaScript ಅನ್ನು ಯಾವಾಗಲೂ ಅನುಮತಿಸಿ</translation> <translation id="5280426389926346830">ಶಾರ್ಟ್ಕಟ್ ರಚಿಸಬೇಕೆ?</translation> <translation id="528208740344463258">Android ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಡೌನ್ಲೋಡ್ ಮಾಡಲು ಮತ್ತು ಬಳಸಲು, ಮೊದಲು ನೀವು ಅಗತ್ಯವಿರುವ ಈ ಅಪ್ಡೇಟ್ ಅನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಬೇಕು. ನಿಮ್ಮ <ph name="DEVICE_TYPE" /> ಅಪ್ಡೇಟ್ ಆಗುತ್ತಿರುವಾಗ, ಅದನ್ನು ಬಳಸಲು ನಿಮಗೆ ಸಾಧ್ಯವಿಲ್ಲ. ಇನ್ಸ್ಟಾಲ್ ಮಾಡುವಿಕೆ ಪೂರ್ಣಗೊಂಡ ನಂತರ, ನಿಮ್ಮ <ph name="DEVICE_TYPE" /> ಮರುಪ್ರಾರಂಭವಾಗುತ್ತದೆ.</translation> @@ -2862,7 +2847,6 @@ <translation id="5449551289610225147">ಅಮಾನ್ಯ ಪಾಸ್ವರ್ಡ್</translation> <translation id="5449588825071916739">ಎಲ್ಲಾ ಟ್ಯಾಬ್ಗಳನ್ನು ಬುಕ್ಮಾರ್ಕ್ ಮಾಡಿ</translation> <translation id="5449716055534515760">&ವಿಂಡೋ ಮುಚ್ಚಿರಿ</translation> -<translation id="5453029940327926427">ಟ್ಯಾಬ್ಗಳನ್ನು ಮುಚ್ಚಿ </translation> <translation id="5454166040603940656"><ph name="PROVIDER" /> ಜೊತೆಗೆ</translation> <translation id="5457113250005438886">ಅಮಾನ್ಯ</translation> <translation id="5457459357461771897">ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ನಿಂದ ಫೋಟೋಗಳು, ಸಂಗೀತ, ಮತ್ತು ಇತರ ಮಾಧ್ಯಮವನ್ನು ಓದಿರಿ ಮತ್ತು ಅಳಿಸಿ</translation> @@ -3326,7 +3310,6 @@ <translation id="6122875415561139701">ಈ ಸಾಧನದಲ್ಲಿ ಬರೆಯುವಿಕೆ ಕಾರ್ಯಾಚರಣೆಯನ್ನು ಅನುಮತಿಸಲಾಗಿಲ್ಲ: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">ಕೆಳಗಿನ ವಿಸ್ತರಣೆಗಳು ಈ ವಿಸ್ತರಣೆಯ ಮೇಲೆ ಅವಲಂಬಿತವಾಗಿವೆ:</translation> <translation id="6125479973208104919">ದುರದೃಷ್ಟವಶಾತ್, ನಿಮ್ಮ ಖಾತೆಯನ್ನು ನೀವು ಮತ್ತೆ ಈ <ph name="DEVICE_TYPE" /> ಗೆ ಸೇರಿಸುವ ಅಗತ್ಯವಿದೆ.</translation> -<translation id="612596694132302162">ಸೈಟ್ ಅನ್ನು ಅನ್ಮ್ಯೂಟ್ ಮಾಡಿ</translation> <translation id="6129691635767514872">ಆಯ್ಕೆಮಾಡಲಾದ ಡೇಟಾವನ್ನು Chrome ಮತ್ತು ಸಿಂಕ್ ಮಾಡಲ್ಪಟ್ಟ ಸಾಧನಗಳಿಂದ ತೆಗೆದುಹಾಕಲಾಗಿದೆ. ನಿಮ್ಮ Google ಖಾತೆಯು <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" />ನಲ್ಲಿನ ಇತರ Google ಸೇವೆಗಳಲ್ಲಿ ಹುಡುಕಾಟಗಳು ಮತ್ತು ಚಟುವಟಿಕೆಯಂತಹ ಬ್ರೌಸಿಂಗ್ ಹುಡುಕಾಟಗಳ ಇತರ ಪ್ರಕಾರಗಳನ್ನು ಹೊಂದಿರಬಹುದು.</translation> <translation id="6129938384427316298">Netscape ಪ್ರಮಾಣಪತ್ರ ಕಾಮೆಂಟ್</translation> <translation id="6129953537138746214">ಸ್ಪೇಸ್</translation> @@ -3529,7 +3512,6 @@ <translation id="6436164536244065364">ವೆಬ್ ಅಂಗಡಿಯಲ್ಲಿ ವೀಕ್ಷಿಸಿ</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - ಆಡಿಯೋ ಪ್ಲೇ ಆಗುತ್ತಿದೆ</translation> <translation id="6442187272350399447">ಆಕರ್ಷಕ</translation> -<translation id="6442697326824312960">ಟ್ಯಾಬ್ ಅನ್ಪಿನ್ ಮಾಡಿ</translation> <translation id="6444070574980481588">ದಿನಾಂಕ ಮತ್ತು ಸಮಯವನ್ನು ಹೊಂದಿಸಿ</translation> <translation id="6445450263907939268">ನಿಮಗೆ ಈ ಬದಲಾವಣೆಗಳು ಅಗತ್ಯವಿಲ್ಲದಿದ್ದರೆ, ನಿಮ್ಮ ಹಿಂದಿನ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ನೀವು ಪುನಃಸ್ಥಾಪಿಸಬಹುದು.</translation> <translation id="6447842834002726250">ಕುಕೀಸ್</translation> @@ -3732,7 +3714,6 @@ <translation id="6770664076092644100">NFC ಮೂಲಕ ಪರಿಶೀಲಿಸಿ</translation> <translation id="6771503742377376720">ಪ್ರಮಾಣಪತ್ರ ಪ್ರಾಧಿಕಾರವಾಗಿದೆ</translation> <translation id="6777817260680419853">ಮರುನಿರ್ದೇಶಿಸುವಿಕೆಯನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ</translation> -<translation id="6778959797435875428">ಸೈಟ್ಗಳನ್ನು ಅನ್ಮ್ಯೂಟ್ ಮಾಡಿ</translation> <translation id="677965093459947883">ತುಂಬಾ ಚಿಕ್ಕದು</translation> <translation id="6780439250949340171">ಇತರ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ನಿರ್ವಹಿಸಿ</translation> <translation id="6781284683813954823">ಡೂಡಲ್ ಲಿಂಕ್</translation> @@ -4049,7 +4030,6 @@ <translation id="7257666756905341374">ನೀವು ನಕಲಿಸಿದ ಮತ್ತು ಅಂಟಿಸಿದ ಡೇಟಾವನ್ನು ಓದಿರಿ</translation> <translation id="7258697411818564379">ನಿಮ್ಮ ಪಿನ್ ಸೇರಿಸಲಾಗಿದೆ</translation> <translation id="7262004276116528033">ಈ ಸೈನ್ ಇನ್ ಸೇವೆಯನ್ನು <ph name="SAML_DOMAIN" /> ಮೂಲಕ ಹೋಸ್ಟ್ ಮಾಡಲಾಗಿದೆ</translation> -<translation id="7268365133021434339">ಟ್ಯಾಬ್ಗಳನ್ನು ಮುಚ್ಚಿ</translation> <translation id="7268659760406822741">ಲಭ್ಯವಿರುವ ಸೇವೆಗಳು</translation> <translation id="7270858098575133036">MIDI ಸಾಧನಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ಸೈಟ್ವೊಂದು ಸಿಸ್ಟಮ್ನ ಪ್ರತ್ಯೇಕ ಸಂದೇಶಗಳನ್ನು ಬಳಸಬೇಕೆಂದಾಗ ನನ್ನನ್ನು ಕೇಳಿ</translation> <translation id="7272674038937250585">ಯಾವುದೇ ವಿವರಣೆಯನ್ನು ಒದಗಿಸಿಲ್ಲ</translation> @@ -4237,7 +4217,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">ಹೋಲಿಸಿ ನೋಡು</translation> <translation id="7576976045740938453">ಡೆಮೊ ಮೋಡ್ ಖಾತೆಯಲ್ಲಿ ಸಮಸ್ಯೆ ಸಂಭವಿಸಿದೆ.</translation> -<translation id="7579149537961810247">ಸೈಟ್ಗಳನ್ನು ಮ್ಯೂಟ್ ಮಾಡಿ</translation> <translation id="7580671184200851182">ಎಲ್ಲಾ ಸ್ಪೀಕರ್ಗಳ ಮೂಲಕ ಒಂದೇ ಆಡಿಯೋ ಪ್ಲೇ ಮಾಡಿ (ಮೋನೋ ಆಡಿಯೋ)</translation> <translation id="7581462281756524039">ಕ್ಲೀನಪ್ ಪರಿಕರ</translation> <translation id="7582582252461552277">ಈ ನೆಟ್ವರ್ಕ್ಗೆ ಆದ್ಯತೆ ನೀಡಿ</translation> @@ -4584,7 +4563,6 @@ <translation id="8068253693380742035">ಸೈನ್ ಇನ್ ಮಾಡಲು ಸ್ಪರ್ಶಿಸಿ</translation> <translation id="8069615408251337349">Google ಮೇಘ ಮುದ್ರಣ</translation> <translation id="8071432093239591881">ಚಿತ್ರದಂತೆ ಪ್ರಿಂಟ್ ಮಾಡಿ</translation> -<translation id="8072988827236813198">ಪಿನ್ ಟ್ಯಾಬ್ಗಳು</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />ಆ್ಯಪ್ ಡೇಟಾವು ಸಂಪರ್ಕಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಫೋಟೋಗಳಂತಹ ಡೇಟಾ ಸೇರಿದಂತೆ, ಆ್ಯಪ್ ಉಳಿಸಿರುವಂತಹ (ಡೆವಲಪರ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಆಧರಿಸಿ) ಯಾವುದೇ ಡೇಟಾ ಆಗಿರಬಹುದು.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />ಬ್ಯಾಕಪ್ ಡೇಟಾವನ್ನು ನಿಮ್ಮ ಮಗುವಿನ ಡ್ರೈವ್ ಸಂಗ್ರಹಣೆ ಕೋಟಾದಲ್ಲಿ ಪರಿಗಣಿಸಲಾಗುವುದಿಲ್ಲ.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />ನೀವು ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ ಈ ಸೇವೆಯನ್ನು ಆಫ್ ಮಾಡಬಹುದು.<ph name="END_PARAGRAPH3" /></translation> @@ -4771,7 +4749,6 @@ <translation id="8368859634510605990">&ಎಲ್ಲ ಬುಕ್ಮಾರ್ಕ್ಗಳನ್ನು ತೆರೆಯಿರಿ</translation> <translation id="8371695176452482769">ಈಗ ಮಾತನಾಡಿ</translation> <translation id="8372369524088641025">ಕೆಟ್ಟ WEP ಕೀ</translation> -<translation id="8373553483208508744">ಟ್ಯಾಬ್ಗಳನ್ನು ಮ್ಯೂಟ್ ಮಾಡಿ</translation> <translation id="8378714024927312812">ನಿಮ್ಮ ಸಂಸ್ಥೆಯ ಮೂಲಕ ನಿರ್ವಹಿಸಲಾಗಿದೆ</translation> <translation id="8379878387931047019">ಈ ವೆಬ್ಸೈಟ್ ವಿನಂತಿಸಿದ ಸುರಕ್ಷತಾ ಕೀಯ ಪ್ರಕಾರವನ್ನು ಈ ಸಾಧನ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ</translation> <translation id="8382913212082956454">ಇಮೇಲ್ &ವಿಳಾಸವನ್ನು ನಕಲು ಮಾಡಿ</translation> @@ -4881,7 +4858,6 @@ <translation id="8546930481464505581">ಸ್ಪರ್ಶ ಪಟ್ಟಿಯನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ</translation> <translation id="8547013269961688403">ಪೂರ್ಣಪರದೆ ವರ್ಧಕವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ</translation> <translation id="85486688517848470">ಮೇಲಿನ-ಸಾಲುಗಳ ಕೀಗಳ ನಡುವಳಿಕೆಯನ್ನು ಬದಲಾಯಿಸಲು ಹುಡುಕಾಟದ ಕೀ ಅನ್ನು ಒತ್ತಿ ಹಿಡಿಯಿರಿ</translation> -<translation id="855081842937141170">ಪಿನ್ ಟ್ಯಾಬ್</translation> <translation id="8551388862522347954">ಪರವಾನಗಿಗಳು</translation> <translation id="8553342806078037065">ಇತರ ವ್ಯಕ್ತಿಗಳನ್ನು ನಿರ್ವಹಿಸು</translation> <translation id="8554899698005018844">ಭಾಷೆ ನಮೂದಿಸಿಲ್ಲ</translation> @@ -5195,7 +5171,6 @@ <translation id="9038430547971207796">ಮುಂದಿನ ಬಾರಿ, ನಿಮ್ಮ ಫೋನ್ <ph name="DEVICE_TYPE" /> ಸಾಧನವನ್ನು ಅನ್ಲಾಕ್ ಮಾಡುತ್ತದೆ. ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ Smart Lock ಅನ್ನು ಆಫ್ ಮಾಡಿ.</translation> <translation id="9038649477754266430">ಪುಟಗಳನ್ನು ಹೆಚ್ಚು ವೇಗವಾಗಿ ಲೋಡ್ ಮಾಡಲು ಮುನ್ನೋಟಗಳನ್ನು ಬಳಸಿ</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">ಟ್ಯಾಬ್ಗಳನ್ನು ಮ್ಯೂಟ್ ಮಾಡಿ</translation> <translation id="9040661932550800571"><ph name="ORIGIN" /> ಗಾಗಿ ಪಾಸ್ವರ್ಡ್ ಅಪ್ಡೇಟ್ ಮಾಡುವುದೇ?</translation> <translation id="9041692268811217999">ನಿಮ್ಮ ಯಂತ್ರದಲ್ಲಿ ಸ್ಥಳೀಯ ಫೈಲ್ಗಳಿಗೆ ಪ್ರವೇಶಿಸುವುದನ್ನು ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ</translation> <translation id="9042893549633094279">ಗೌಪ್ಯತೆ ಮತ್ತು ಭದ್ರತೆ</translation> @@ -5294,7 +5269,6 @@ <translation id="9201220332032049474">ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಆಯ್ಕೆಗಳು</translation> <translation id="9203398526606335860">&ಪ್ರೊಫೈಲಿಂಗ್ ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ </translation> -<translation id="9203478404496196495">ಟ್ಯಾಬ್ ಅನ್ನು ಅನ್ ಮ್ಯೂಟ್ ಮಾಡಿ</translation> <translation id="9203904171912129171">ಸಾಧನವನ್ನು ಆಯ್ಕೆಮಾಡಿ</translation> <translation id="9203962528777363226">ಈ ಸಾಧನದ ನಿರ್ವಾಹಕರು ಸೇರಿಸುವ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ</translation> <translation id="9213073329713032541">ಇನ್ಸ್ಟಾಲ್ ಮಾಡುವಿಕೆಯು ಯಶಸ್ವಿಯಾಗಿ ಆರಂಭಗೊಂಡಿದೆ.</translation>
diff --git a/chrome/app/resources/generated_resources_ko.xtb b/chrome/app/resources/generated_resources_ko.xtb index a99c142..d6f1c39b 100644 --- a/chrome/app/resources/generated_resources_ko.xtb +++ b/chrome/app/resources/generated_resources_ko.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">건너뛰려면 Esc 키를 누르세요(비공식 빌드만 해당).</translation> <translation id="1093457606523402488">표시된 네트워크:</translation> <translation id="1094607894174825014">기기(<ph name="DEVICE_NAME" />)에서 잘못된 오프셋으로 읽기 또는 쓰기 작업을 요청했습니다.</translation> -<translation id="109758035718544977">사이트 음소거 해제</translation> <translation id="1097658378307015415">로그인하기 전에 게스트로 로그인하여 <ph name="NETWORK_ID" /> 네트워크를 활성화하세요.</translation> <translation id="1103523840287552314"><ph name="LANGUAGE" /> 항상 번역</translation> <translation id="1108600514891325577">중지(&S)</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">시크릿 창에서는 인터넷 사용 기록을 저장하지 않고 웹을 사용할 수 있습니다.</translation> <translation id="1213037489357051291">지문 <ph name="NUM_FINGERPRINTS" />개 설정됨</translation> <translation id="1215411991991485844">새 백그라운드 앱을 추가함</translation> -<translation id="1216654534877302979">사이트 음소거</translation> <translation id="1216659994753476700">죄송합니다. 프로필에 액세스할 수 없습니다. 기기에 저장된 파일 및 데이터가 손실될 수 있습니다.<ph name="BR" /> <ph name="BR" /> 프로필을 다시 설정해야 합니다.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Google 드라이브 계정에 데이터 저장</translation> <translation id="1288037062697528143">일몰 시 야간 조명이 자동으로 켜짐</translation> <translation id="1288300545283011870">음성 속성</translation> -<translation id="1293177648337752319">사이트 음소거 해제</translation> <translation id="1293264513303784526">USB-C 기기(왼쪽 포트)</translation> <translation id="1293556467332435079">파일</translation> <translation id="1296497012903089238">인증서 유형</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">홈페이지가 새 탭 페이지입니다.</translation> <translation id="1436671784520050284">설정 계속하기</translation> <translation id="1436784010935106834">삭제됨</translation> -<translation id="1438632560381091872">탭 음소거 해제</translation> <translation id="1442392616396121389">라우팅 프리픽스</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" />개가 선택되었습니다</translation> <translation id="1444628761356461360">기기 소유자인 <ph name="OWNER_EMAIL" />이(가) 관리하는 설정입니다.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">마지막으로 비밀번호를 입력한 후 다른 키보드가 연결되었습니다. 키 입력 내용을 도용하려는 시도일 수 있습니다.</translation> <translation id="1567750922576943685">신원을 인증하면 개인정보를 보호하는 데 도움이 됩니다.</translation> <translation id="1567993339577891801">자바스크립트 콘솔</translation> -<translation id="1568067597247500137">사이트 음소거</translation> <translation id="1568323446248056064">디스플레이 기기 설정 열기</translation> <translation id="1572266655485775982">Wi-Fi 사용</translation> <translation id="1572585716423026576">배경화면으로 설정</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">SHA-1을 포함한 X9.62 ECDSA 서명</translation> <translation id="1644574205037202324">방문 기록</translation> <translation id="1645516838734033527">Smart Lock을 사용하려면 <ph name="DEVICE_TYPE" />의 보안 유지를 위해 휴대전화에 화면 잠금을 설정해야 합니다.</translation> -<translation id="1646102270785326155">이 사용자를 제거하면 해당 사용자와 연결된 모든 파일 및 로컬 데이터가 영구적으로 삭제됩니다. $1은(는) 나중에 또 로그인할 수 있습니다.</translation> <translation id="1646982517418478057">이 인증서를 암호화하려면 비밀번호를 입력하세요.</translation> <translation id="164814987133974965">관리 대상 사용자는 관리자가 정한 범위 내에서 웹을 탐색할 수 있습니다. 관리 대상 사용자의 관리자는 Chrome에서 다음을 수행할 수 있습니다. 특정 웹사이트 <ph name="BEGIN_BOLD" />허용 또는 금지<ph name="END_BOLD" /> @@ -499,7 +493,6 @@ <translation id="1729533290416704613">또한 검색주소창에서 검색할 때 표시되는 페이지를 설정합니다.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />앱을 삭제하려면 설정 > Google Play 스토어 > Android 환경설정 관리 > 앱 또는 애플리케이션 관리자로 이동합니다. 그런 다음 제거하려는 앱을 탭합니다(앱을 찾으려면 오른쪽이나 왼쪽으로 스와이프해야 할 수 있음). 그런 다음 제거 또는 사용 중지를 탭합니다.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">요청하는 중...</translation> -<translation id="1732215134274276513">탭 고정 해제</translation> <translation id="1733383495376208985">나만의 <ph name="BEGIN_LINK" />동기화 암호<ph name="END_LINK" />로 동기화된 데이터를 암호화합니다. Google Pay의 결제 수단 및 주소는 암호화되지 않습니다.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" />에서 자동 업데이트를 수행하지 못할 수 있습니다</translation> <translation id="1736419249208073774">탐색</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">모든 파일</translation> <translation id="1809734401532861917">북마크, 방문 기록, 비밀번호, 기타 설정을 <ph name="USER_EMAIL_ADDRESS" />에 추가합니다.</translation> <translation id="1810764548349082891">미리보기 없음</translation> -<translation id="1812631533912615985">탭 고정 해제</translation> <translation id="1813278315230285598">서비스</translation> <translation id="18139523105317219">EDI측 이름</translation> <translation id="1815083418640426271">일반 텍스트로 붙여넣기</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chrome이 자동화된 테스트 소프트웨어에 의해 제어되고 있습니다.</translation> <translation id="2070909990982335904">점(.)으로 시작하는 이름은 시스템 전용입니다. 다른 이름을 선택하세요.</translation> <translation id="2071393345806050157">로컬 로그 파일이 없습니다.</translation> -<translation id="2074527029802029717">탭 고정 해제</translation> <translation id="2075474481720804517">배터리 <ph name="BATTERY_PERCENTAGE" />% 남음</translation> <translation id="2075959085554270910">탭하여 클릭 및 탭 드래그를 사용/사용 중지하도록 허용합니다.</translation> <translation id="2076269580855484719">이 플러그인 숨기기</translation> @@ -1352,7 +1343,6 @@ <translation id="3045447014237878114">이 사이트에서 여러 파일을 자동으로 다운로드함</translation> <translation id="3046910703532196514">웹페이지, 전부</translation> <translation id="304747341537320566">음성 엔진</translation> -<translation id="304826556400666995">탭 음소거 해제</translation> <translation id="3053013834507634016">인증서 키 사용</translation> <translation id="3057861065630527966">사진 및 동영상을 백업합니다.</translation> <translation id="3060379269883947824">텍스트 읽어주기 사용</translation> @@ -2333,7 +2323,6 @@ <translation id="4628762811416793313">Linux 컨테이너 설정이 완료되지 않았습니다. 다시 시도해 주세요.</translation> <translation id="4628948037717959914">사진</translation> <translation id="4631887759990505102">아티스트</translation> -<translation id="4632483769545853758">탭 음소거 해제</translation> <translation id="4633003931260532286">확장 프로그램은 최소 버전 '<ph name="IMPORT_VERSION" />'의 '<ph name="IMPORT_NAME" />'을(를) 요구하지만 '<ph name="INSTALLED_VERSION" />' 버전만 설치되었습니다</translation> <translation id="4634771451598206121">다시 로그인...</translation> <translation id="4635398712689569051">게스트 사용자는 <ph name="PAGE_NAME" />을(를) 사용할 수 없음</translation> @@ -2397,7 +2386,6 @@ <translation id="4735803855089279419">시스템에서 이 기기의 기기 식별자를 확인하지 못했습니다.</translation> <translation id="4737715515457435632">네트워크에 연결하세요.</translation> <translation id="473775607612524610">업데이트</translation> -<translation id="474217410105706308">탭 음소거</translation> <translation id="4742746985488890273">임시보관함에 고정</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />애플리케이션 업데이트 방법 알아보기<ph name="END_LINK" /></translation> <translation id="4746351372139058112">메시지</translation> @@ -2622,7 +2610,6 @@ <translation id="5094721898978802975">협력 중인 기본 애플리케이션과 통신</translation> <translation id="5097002363526479830">'<ph name="NAME" />' 네트워크에 연결하지 못했습니다: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">모든 북마크 열기</translation> -<translation id="5105855035535475848">탭 고정</translation> <translation id="5108967062857032718">설정 - Android 앱 삭제</translation> <translation id="5109044022078737958">미미</translation> <translation id="5111692334209731439">북마크 관리자(&B)</translation> @@ -2687,7 +2674,6 @@ <translation id="520621735928254154">인증서 가져오기 오류</translation> <translation id="5209320130288484488">기기를 찾을 수 없음</translation> <translation id="5209518306177824490">SHA-1 지문</translation> -<translation id="5210365745912300556">탭 닫기</translation> <translation id="5213481667492808996">'<ph name="NAME" />' 데이터 서비스를 사용할 수 있습니다.</translation> <translation id="5213891612754844763">프록시 설정 표시</translation> <translation id="521582610500777512">사진이 삭제되었습니다.</translation> @@ -2738,7 +2724,6 @@ <translation id="5270167208902136840"><ph name="NUMBER_OF_MORE_APPS" />개 앱 더 표시</translation> <translation id="5275352920323889391">개</translation> <translation id="5275973617553375938">Google 드라이브에서 복구된 파일</translation> -<translation id="527605719918376753">탭 음소거</translation> <translation id="527605982717517565"><ph name="HOST" />에서 자바스크립트 항상 허용</translation> <translation id="5280426389926346830">바로가기를 만드시겠습니까?</translation> <translation id="528208740344463258">Android 앱을 다운로드하고 사용하려면 우선 필수 업데이트를 설치해야 합니다. 업데이트 중에는 <ph name="DEVICE_TYPE" /> 기기를 사용할 수 없습니다. 설치가 완료되면 <ph name="DEVICE_TYPE" /> 기기가 다시 시작됩니다.</translation> @@ -2861,7 +2846,6 @@ <translation id="5449551289610225147">비밀번호가 잘못되었습니다.</translation> <translation id="5449588825071916739">모든 탭 북마크</translation> <translation id="5449716055534515760">창 닫기(&D)</translation> -<translation id="5453029940327926427">탭 닫기</translation> <translation id="5454166040603940656">제공업체: <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">잘못된 데이터</translation> <translation id="5457459357461771897">컴퓨터에서 사진, 음악, 기타 미디어 조회 및 삭제</translation> @@ -3326,7 +3310,6 @@ <translation id="6122875415561139701">기기(<ph name="DEVICE_NAME" />)에서 쓰기 작업이 허용되지 않습니다.</translation> <translation id="6124650939968185064">이 확장 프로그램에 종속되는 확장 프로그램:</translation> <translation id="6125479973208104919">이 <ph name="DEVICE_TYPE" />에 계정을 다시 추가해야 합니다.</translation> -<translation id="612596694132302162">사이트 음소거 해제</translation> <translation id="6129691635767514872">선택한 데이터가 Chrome 및 동기화된 기기에서 삭제되었습니다. <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />에서 검색이나 기타 Google 서비스에서의 활동 등 내 Google 계정에 있는 다른 형식의 탐색 기록을 확인할 수 있습니다.</translation> <translation id="6129938384427316298">Netscape Certificate Comment</translation> <translation id="6129953537138746214">공백</translation> @@ -3529,7 +3512,6 @@ <translation id="6436164536244065364">웹 스토어에서 보기</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - 오디오 재생</translation> <translation id="6442187272350399447">멋쟁이</translation> -<translation id="6442697326824312960">탭 고정 해제</translation> <translation id="6444070574980481588">날짜 및 시간 설정</translation> <translation id="6445450263907939268">변경하지 않으려는 경우 이전 설정을 복원할 수 있습니다.</translation> <translation id="6447842834002726250">쿠키</translation> @@ -3732,7 +3714,6 @@ <translation id="6770664076092644100">NFC를 통해 인증</translation> <translation id="6771503742377376720">인증 기관임</translation> <translation id="6777817260680419853">리디렉션이 차단됨</translation> -<translation id="6778959797435875428">사이트 음소거 해제</translation> <translation id="677965093459947883">아주 작게</translation> <translation id="6780439250949340171">기타 설정 관리</translation> <translation id="6781284683813954823">기념일 로고 링크</translation> @@ -4049,7 +4030,6 @@ <translation id="7257666756905341374">복사하여 붙여넣은 데이터 조회</translation> <translation id="7258697411818564379">PIN이 추가됨</translation> <translation id="7262004276116528033">이 로그인 서비스는 <ph name="SAML_DOMAIN" />에서 호스팅됩니다.</translation> -<translation id="7268365133021434339">탭 닫기</translation> <translation id="7268659760406822741">사용 가능한 서비스</translation> <translation id="7270858098575133036">사이트에서 시스템 전용 메시지를 사용하여 MIDI 기기에 액세스하려는 경우 확인</translation> <translation id="7272674038937250585">제공된 설명이 없음</translation> @@ -4239,7 +4219,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">한 부씩 인쇄</translation> <translation id="7576976045740938453">데모 모드 계정에 문제가 발생했습니다.</translation> -<translation id="7579149537961810247">사이트 음소거</translation> <translation id="7580671184200851182">모든 스피커에서 동일한 오디오 실행(모노 오디오)</translation> <translation id="7581462281756524039">정리도구</translation> <translation id="7582582252461552277">이 네트워크를 사용</translation> @@ -4593,7 +4572,6 @@ <translation id="8068253693380742035">로그인하려면 터치하세요.</translation> <translation id="8069615408251337349">Google 클라우드 프린트</translation> <translation id="8071432093239591881">이미지로 인쇄</translation> -<translation id="8072988827236813198">탭 고정</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />앱 데이터에는 연락처, 메시지, 사진 등 앱에서 개발자 설정에 따라 저장한 모든 데이터가 포함될 수 있습니다.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />백업 데이터는 자녀의 드라이브 스토리지 용량에 포함되지 않습니다.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />설정에서 이 서비스를 사용 중지할 수 있습니다.<ph name="END_PARAGRAPH3" /></translation> @@ -4779,7 +4757,6 @@ <translation id="8368859634510605990">모든 북마크 열기(&O)</translation> <translation id="8371695176452482769">말하세요</translation> <translation id="8372369524088641025">잘못된 WEP 키</translation> -<translation id="8373553483208508744">탭 음소거</translation> <translation id="8378714024927312812">조직에서 관리</translation> <translation id="8379878387931047019">이 기기는 이 웹사이트에서 요청하는 유형의 보안 키를 지원하지 않습니다.</translation> <translation id="8382913212082956454">이메일 주소 복사(&E)</translation> @@ -4887,7 +4864,6 @@ <translation id="8546930481464505581">Touch Bar 맞춤설정</translation> <translation id="8547013269961688403">전체화면 돋보기 사용</translation> <translation id="85486688517848470">맨 위 키의 동작을 전환하려면 검색 키를 길게 누름</translation> -<translation id="855081842937141170">탭 고정</translation> <translation id="8551388862522347954">라이선스</translation> <translation id="8553342806078037065">다른 사용자 관리</translation> <translation id="8554899698005018844">언어가 없음</translation> @@ -5201,7 +5177,6 @@ <translation id="9038430547971207796">다음번에는 휴대전화를 통해 <ph name="DEVICE_TYPE" />이(가) 잠금 해제됩니다. 설정에서 Smart Lock을 사용 중지하세요.</translation> <translation id="9038649477754266430">빠른 페이지 로드를 위해 예상 검색어 서비스 사용</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">탭 음소거</translation> <translation id="9040661932550800571"><ph name="ORIGIN" /> 비밀번호를 업데이트하시겠습니까?</translation> <translation id="9041692268811217999">관리자가 시스템의 로컬 파일 액세스를 차단했습니다</translation> <translation id="9042893549633094279">개인정보 및 보안</translation> @@ -5299,7 +5274,6 @@ <translation id="920045321358709304"><ph name="SEARCH_ENGINE" /> 검색</translation> <translation id="9201220332032049474">화면 잠금 옵션</translation> <translation id="9203398526606335860">프로파일링 사용(&P)</translation> -<translation id="9203478404496196495">탭 음소거 해제</translation> <translation id="9203904171912129171">기기를 선택하세요.</translation> <translation id="9203962528777363226">이 기기의 관리자가 새로운 사용자를 추가하지 못하도록 설정함</translation> <translation id="9213073329713032541">설치가 시작되었습니다.</translation>
diff --git a/chrome/app/resources/generated_resources_lt.xtb b/chrome/app/resources/generated_resources_lt.xtb index 579ce665..e06ac56 100644 --- a/chrome/app/resources/generated_resources_lt.xtb +++ b/chrome/app/resources/generated_resources_lt.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Jei norite praleisti, paspauskite ESCAPE (galioja tik neoficialioms versijoms).</translation> <translation id="1093457606523402488">Matomi tinklai:</translation> <translation id="1094607894174825014">Buvo pateikta skaitymo arba rašymo operacijos užklausa su netinkamu poslinkiu įrenginyje „<ph name="DEVICE_NAME" />“.</translation> -<translation id="109758035718544977">Įjungti svetainių garsą</translation> <translation id="1097658378307015415">Prieš prisijungdami įeikite kaip svečias, kad suaktyvintumėte tinklą <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Visada versti <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Sustabdyti</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Naršykite žiniatinklį neišsaugodami naršymo istorijos inkognito lange</translation> <translation id="1213037489357051291">Nustatyta kontrolinių kodų: <ph name="NUM_FINGERPRINTS" /></translation> <translation id="1215411991991485844">Pridėta nauja foninė programa</translation> -<translation id="1216654534877302979">Nutildyti svetaines</translation> <translation id="1216659994753476700">Apgailestaujame. Negalime pasiekti jūsų profilio. Galite prarasti šiame įrenginyje saugomus failus ir duomenis.<ph name="BR" /> <ph name="BR" /> Turėsite dar kartą nustatyti profilį.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Saugoti duomenis „Google“ disko paskyroje</translation> <translation id="1288037062697528143">Nakties šviesa bus įjungta automatiškai saulei leidžiantis</translation> <translation id="1288300545283011870">Kalbos ypatybės</translation> -<translation id="1293177648337752319">Įjungti svetainės garsą</translation> <translation id="1293264513303784526">USB-C įrenginys (prievadas kairėje)</translation> <translation id="1293556467332435079">Failai</translation> <translation id="1296497012903089238">Sertifikato tipas</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Pagrindinis puslapis yra naujo skirtuko puslapis</translation> <translation id="1436671784520050284">Tęsti sąranką</translation> <translation id="1436784010935106834">Pašalinta</translation> -<translation id="1438632560381091872">Įjungti garsą skirtukuose</translation> <translation id="1442392616396121389">Nukreipimo priešdėlis</translation> <translation id="144283815522798837">Pasirinkta: <ph name="NUMBER_OF_ITEMS_SELECTED" /></translation> <translation id="1444628761356461360">Šį nustatymą tvarko įrenginio savininkas (<ph name="OWNER_EMAIL" />).</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Po to, kai paskutinį kartą įvedėte slaptažodį, buvo prijungta kita klaviatūra. Gali būti bandoma pavogti jūsų klavišų paspaudimus.</translation> <translation id="1567750922576943685">Jei patvirtinsite savo tapatybę, galėsime efektyviau apsaugoti asmens informaciją</translation> <translation id="1567993339577891801">„JavaScript“ pultas</translation> -<translation id="1568067597247500137">Nutildyti svetainę</translation> <translation id="1568323446248056064">Atidaryti įrenginio pateikties nustatymus</translation> <translation id="1572266655485775982">Įgalinti „Wi-Fi“</translation> <translation id="1572585716423026576">Nustatyti kaip foną</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">X9.62 ECDSA parašas naudojant SHA-1</translation> <translation id="1644574205037202324">Istorija</translation> <translation id="1645516838734033527">Kad būtų galima apsaugoti „<ph name="DEVICE_TYPE" />“, „Smart Lock“ reikia užrakinti telefono ekraną.</translation> -<translation id="1646102270785326155">Visi failai ir su šiuo naudotoju susiję vietiniai duomenys bus ištrinti visam laikui, kai šis naudotojas bus pašalintas. $1 vis tiek galės vėliau prisijungti.</translation> <translation id="1646982517418478057">Kad užšifruotumėte šį sertifikatą, įveskite slaptažodį</translation> <translation id="164814987133974965">Prižiūrimas naudotojas gali naršyti žiniatinklį jums prižiūrint. Kaip prižiūrimo naudotojo valdytojas (-a) galite <ph name="BEGIN_BOLD" />leisti arba uždrausti<ph name="END_BOLD" /> tam tikras svetaines, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Ji taip pat kontroliuoja, koks puslapis rodomas, kai ieškote „Omnibox“.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Jei norite pašalinti programas, eikite į skiltį „Nustatymai“ > „Google Play“ parduotuvė“ > „Tvarkyti „Android“ nuostatas“ > „Programos“ arba „Programų tvarkytuvė“. Tada palieskite programą, kurią norite pašalinti (gali reikėti perbraukti į dešinę arba į kairę, kad rastumėte programą). Tada palieskite „Pašalinti“ arba „Išjungti“.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Siunčiama užklausa...</translation> -<translation id="1732215134274276513">Atsegti skirtukus</translation> <translation id="1733383495376208985">Šifruokite sinchronizuojamus duomenis taikydami savo <ph name="BEGIN_LINK" />sinchronizavimo slaptafrazę<ph name="END_LINK" />. Neįtraukiami mokėjimo metodai ir adresai iš „Google Pay“.</translation> <translation id="1734824808160898225">„<ph name="PRODUCT_NAME" />“ gali nesugebėti atsinaujinti</translation> <translation id="1736419249208073774">Naršyti</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Visi failai</translation> <translation id="1809734401532861917">Pridėti mano žymes, istoriją, slaptažodžius ir kitus nustatymus prie <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Peržiūra negalima</translation> -<translation id="1812631533912615985">Atsegti skirtukus</translation> <translation id="1813278315230285598">Paslaugos</translation> <translation id="18139523105317219">EDI šalies pavadinimas</translation> <translation id="1815083418640426271">Įklijuoti kaip grynąjį tekstą</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">„Chrome“ valdoma naudojant automatinę bandomąją programinę įrangą.</translation> <translation id="2070909990982335904">Tašku prasidedantys pavadinimai rezervuoti sistemai. Pasirinkite kitą pavadinimą.</translation> <translation id="2071393345806050157">Nėra vietinio žurnalo failo.</translation> -<translation id="2074527029802029717">Atsegti skirtuką</translation> <translation id="2075474481720804517">Akumuliatorius: <ph name="BATTERY_PERCENTAGE" /> %</translation> <translation id="2075959085554270910">Suteikia galimybę įgalinti / išjungti funkciją „Paliesti ir spustelėti“ bei vilkimo palietus veiksmus</translation> <translation id="2076269580855484719">Slėpti šį papildinį</translation> @@ -773,6 +764,7 @@ <translation id="215753907730220065">Išeiti iš viso ekrano režimo</translation> <translation id="2157875535253991059">Dabar šis puslapis veikia viso ekrano režimu.</translation> <translation id="216169395504480358">Pridėti „Wi-Fi“...</translation> +<translation id="2162155940152307086">Sinchronizavimas bus pradėtas, kai išeisite iš sinchronizavimo nustatymų</translation> <translation id="2163470535490402084">Prisijunkite prie interneto, kad galėtumėte prisijungti prie „<ph name="DEVICE_TYPE" />“.</translation> <translation id="2166369534954157698">Įlinkdama fechtuotojo špaga sublykčiojo ir pragręžė apvalų arbūzą</translation> <translation id="2169062631698640254">Vis tiek prisijungti</translation> @@ -783,6 +775,7 @@ <translation id="2178098616815594724">Adresu <ph name="PEPPER_PLUGIN_DOMAIN" /> esantis papildinys „<ph name="PEPPER_PLUGIN_NAME" />“ nori pasiekti kompiuterį</translation> <translation id="2178614541317717477">CA pažeidimo galimybė</translation> <translation id="218070003709087997">Skaičiumi nurodykite, kiek kopijų spausdinti (nuo 1 iki 999).</translation> +<translation id="2182253583899676504">Teksto laukuose įvestas tekstas bus siunčiamas į sistemą „Google“.</translation> <translation id="2184515124301515068">Leisti „Chrome“ pasirinkti, kada svetainės gali leisti garsą (rekomenduojama)</translation> <translation id="2187895286714876935">Serverio sertifikato importavimo klaida</translation> <translation id="2187906491731510095">Plėtiniai atnaujinti</translation> @@ -794,7 +787,9 @@ <translation id="2192505247865591433">Iš:</translation> <translation id="2193365732679659387">Patikimumo nustatymai</translation> <translation id="2195729137168608510">El. pašto apsauga</translation> +<translation id="2198757192731523470">„Google“ gali naudoti jūsų istoriją, kad suasmenintų Paiešką, skelbimus ir kitas „Google“ paslaugas.</translation> <translation id="2199298570273670671">Klaida</translation> +<translation id="2199719347983604670">„Chrome“ sinchronizavimo duomenys</translation> <translation id="2200094388063410062">El. paštas</translation> <translation id="2200356397587687044">Norint tęsti „Chrome“ reikia leidimo</translation> <translation id="2200603218210188859">USB įrenginio nuostatos</translation> @@ -1252,6 +1247,7 @@ <translation id="2889064240420137087">Atidaryti nuorodą naudojant...</translation> <translation id="2889925978073739256">Toliau blokuoti ne „smėlio dėžės“ papildinius</translation> <translation id="2893168226686371498">Numatytoji naršyklė</translation> +<translation id="2895734772884435517">Galite bet kuriuo metu sinchronizuoti šiuos nustatymus.</translation> <translation id="289644616180464099">SIM kortelė užrakinta</translation> <translation id="289695669188700754">Rakto ID: <ph name="KEY_ID" /></translation> <translation id="2897878306272793870">Ar tikrai norite atidaryti <ph name="TAB_COUNT" /> skirtukus(-ų)?</translation> @@ -1352,7 +1348,6 @@ <translation id="3045447014237878114">Ši svetainė automatiškai atsisiuntė kelis failus</translation> <translation id="3046910703532196514">Tinklalapis, baigti</translation> <translation id="304747341537320566">Kalbų varikliai</translation> -<translation id="304826556400666995">Įjungti garsą skirtukuose</translation> <translation id="3053013834507634016">Sertifikato rakto naudojimas</translation> <translation id="3057861065630527966">Kurkite atsargines nuotraukų ir vaizdo įrašų kopijas</translation> <translation id="3060379269883947824">Įgalinti funkciją „Teksto ištarimas“</translation> @@ -1721,6 +1716,7 @@ <translation id="3636096452488277381">Sveiki, <ph name="USER_GIVEN_NAME" />.</translation> <translation id="3636766455281737684"><ph name="PERCENTAGE" /> % – liko <ph name="TIME" /></translation> <translation id="3637682276779847508">SIM kortelė bus visam laikui išjungta, jei negalėsite įvesti tinkamo PIN kodo atrakinimo rakto.</translation> +<translation id="363863692969456324">Pataisykite rašybos klaidas naudodami patobulintą rašybos tikrinimo funkciją</translation> <translation id="3640214691812501263">Pridėti „<ph name="EXTENSION_NAME" />“ naudotojui <ph name="USER_NAME" />?</translation> <translation id="3644896802912593514">Plotis</translation> <translation id="3645372836428131288">Truputį pajudinkite pirštą, kad būtų užfiksuota kita piršto antspaudo dalis.</translation> @@ -2153,6 +2149,7 @@ <translation id="4310139701823742692">Failas netinkamo formato. Patikrinkite PPD failą ir bandykite dar kartą.</translation> <translation id="431076611119798497">Išsami informacija</translation> <translation id="4312866146174492540">Užblokuoti (numatytoji parinktis)</translation> +<translation id="4314815835985389558">Sinchronizavimo tvarkymas</translation> <translation id="4316850752623536204">Kūrėjo svetainė</translation> <translation id="4320177379694898372">Nėra interneto ryšio</translation> <translation id="4320948194796820126">Pridėkite žymę prie el. laiško</translation> @@ -2232,6 +2229,7 @@ <translation id="4450974146388585462">Diagnozuoti</translation> <translation id="4451757071857432900">Blokuojama svetainėse, kuriose rodomi nepageidaujami arba klaidinantys skelbimai (rekomenduojama)</translation> <translation id="4453946976636652378">Ieškokite „<ph name="SEARCH_ENGINE_NAME" />“ arba įveskite URL</translation> +<translation id="4461835665417498653">Anonimiškai siunčia tam tikrą sistemos informaciją ir puslapio turinį į sistemą „Google“</translation> <translation id="4462159676511157176">Tinkintų pavadinimų serveriai</translation> <translation id="4467101674048705704">Išskleisti aplanką „<ph name="FOLDER_NAME" />“</translation> <translation id="4469477701382819144">Blokuojama svetainėse, kuriose rodomi nepageidaujami arba klaidinantys skelbimai</translation> @@ -2335,7 +2333,6 @@ <translation id="4628762811416793313">Nepavyko užbaigti „Linux“ sudėtinio rodinio. Bandykite dar kartą.</translation> <translation id="4628948037717959914">Nuotrauka</translation> <translation id="4631887759990505102">Atlikėjas</translation> -<translation id="4632483769545853758">Įjungti skirtuko garsą</translation> <translation id="4633003931260532286">Norint naudoti plėtinį reikalinga bent <ph name="IMPORT_VERSION" /> versijos „<ph name="IMPORT_NAME" />“, bet įdiegta tik <ph name="INSTALLED_VERSION" /> versija</translation> <translation id="4634771451598206121">Prisijungti dar kartą...</translation> <translation id="4635398712689569051">„<ph name="PAGE_NAME" />“ nepasiekiamas svečiams.</translation> @@ -2397,9 +2394,9 @@ <translation id="4735265153267957659">Įveskite slaptažodį, kad įgalintumėte „Smart Lock“. Kitą kartą telefonu bus galima atrakinti „<ph name="DEVICE_TYPE" />“. Funkciją „Smart Lock“ galite išjungti „Nustatymų“ skiltyje.</translation> <translation id="473546211690256853">Šią paskyrą tvarko <ph name="DOMAIN" />.</translation> <translation id="4735803855089279419">Sistemai nepavyko nustatyti šio įrenginio identifikatorių.</translation> +<translation id="4736292055110123391">Sinchronizuokite žymes, slaptažodžius, istoriją ir daugiau visuose savo įrenginiuose</translation> <translation id="4737715515457435632">Prisijunkite prie tinklo</translation> <translation id="473775607612524610">Atnaujinti</translation> -<translation id="474217410105706308">Nutildyti skirtuko garsą</translation> <translation id="4742746985488890273">Prisegti prie lentynos</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Sužinokite, kaip atnaujinti programas<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Pranešimai</translation> @@ -2624,7 +2621,6 @@ <translation id="5094721898978802975">Sąveikauti su atitinkamomis vietinėmis programomis</translation> <translation id="5097002363526479830">Nepavyko prisijungti prie tinklo „<ph name="NAME" />“: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Atidaryti visas žymas</translation> -<translation id="5105855035535475848">Prisegti skirtukus</translation> <translation id="5108967062857032718">Nustatymai – „Android“ programų pašalinimas</translation> <translation id="5109044022078737958">Austra</translation> <translation id="5111692334209731439">&Žymių tvarkytuvė</translation> @@ -2689,7 +2685,6 @@ <translation id="520621735928254154">Sertifikato importavimo klaida</translation> <translation id="5209320130288484488">Įrenginių nerasta</translation> <translation id="5209518306177824490">SHA-1 piršto atspaudas</translation> -<translation id="5210365745912300556">Uždaryti skirtuką</translation> <translation id="5213481667492808996">„<ph name="NAME" />“ duomenų paslauga paruošta naudoti</translation> <translation id="5213891612754844763">Rodyti tarpinio serverio nustatymus</translation> <translation id="521582610500777512">Nuotrauka buvo atmesta</translation> @@ -2738,9 +2733,9 @@ <translation id="5266113311903163739">Sertifikavimo institucijos importavimo klaida</translation> <translation id="5269977353971873915">Spausdinant įvyko klaida</translation> <translation id="5270167208902136840">Rodyti dar <ph name="NUMBER_OF_MORE_APPS" /> progr.</translation> +<translation id="5272654297705279635">Tinkinti nustatymai</translation> <translation id="5275352920323889391">Šuo</translation> <translation id="5275973617553375938">Atkurti failai iš „Google“ disko</translation> -<translation id="527605719918376753">Nutildyti skirtuko garsą</translation> <translation id="527605982717517565">Visada leisti „JavaScript“ <ph name="HOST" /></translation> <translation id="5280426389926346830">Sukurti spartųjį klavišą?</translation> <translation id="528208740344463258">Kad galėtumėte atsisiųsti ir naudoti „Android“ programas, pirmiausia turite įdiegti šį būtiną naujinį. Kol „<ph name="DEVICE_TYPE" />“ atnaujinamas, negalite jo naudoti. Užbaigus diegimą „<ph name="DEVICE_TYPE" />“ bus paleistas iš naujo.</translation> @@ -2863,7 +2858,6 @@ <translation id="5449551289610225147">Netinkamas slaptažodis</translation> <translation id="5449588825071916739">Žymėti visus skirtukus</translation> <translation id="5449716055534515760">Uždaryti lan&gą</translation> -<translation id="5453029940327926427">Uždaryti skirtukus</translation> <translation id="5454166040603940656">naudojant <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Netinkama</translation> <translation id="5457459357461771897">Skaityti ir ištrinti nuotraukas, muziką ir kitą mediją iš kompiuterio</translation> @@ -3329,7 +3323,6 @@ <translation id="6122875415561139701">Rašymo operacija neleidžiama įrenginyje „<ph name="DEVICE_NAME" />“.</translation> <translation id="6124650939968185064">Toliau pateikti plėtiniai priklauso nuo šio plėtinio:</translation> <translation id="6125479973208104919">Deja, reikės vėl pridėti paskyrą šiame „<ph name="DEVICE_TYPE" />“.</translation> -<translation id="612596694132302162">Įjungti svetainės garsą</translation> <translation id="6129691635767514872">Pasirinkti duomenys pašalinti iš „Chrome“ ir sinchronizuojamų įrenginių. „Google“ paskyroje galite būti kitų formų naršymo istorijos, pvz., paieškų ir veiklos iš kitų „Google“ paslaugų, kuri pasiekiama adresu <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">„Netscape“ sertifikato komentaras</translation> <translation id="6129953537138746214">Tarpas</translation> @@ -3532,7 +3525,6 @@ <translation id="6436164536244065364">Žiūrėti internetinėje parduotuvėje</translation> <translation id="6438992844451964465">„<ph name="WINDOW_TITLE" />“ – garso įrašo paleidimas</translation> <translation id="6442187272350399447">Nuostabusis</translation> -<translation id="6442697326824312960">Atsegti skirtuką</translation> <translation id="6444070574980481588">Nustatykite datą ir laiką</translation> <translation id="6445450263907939268">Jei nepageidaujate šių pakeitimų, galite atkurti ankstesnius nustatymus.</translation> <translation id="6447842834002726250">Slapukai</translation> @@ -3735,7 +3727,6 @@ <translation id="6770664076092644100">Patvirtinti per ALR</translation> <translation id="6771503742377376720">Yra sertifikavimo institucija</translation> <translation id="6777817260680419853">Peradresavimas užblokuotas</translation> -<translation id="6778959797435875428">Įjungti svetainių garsą</translation> <translation id="677965093459947883">Labai mažas</translation> <translation id="6780439250949340171">valdyti kitus nustatymus</translation> <translation id="6781284683813954823">Papuošto logotipo nuoroda</translation> @@ -4052,7 +4043,6 @@ <translation id="7257666756905341374">Skaityti kopijuojamus ir įklijuojamus duomenis</translation> <translation id="7258697411818564379">PIN kodas pridėtas</translation> <translation id="7262004276116528033">Ši prisijungimo paslauga priglobiama <ph name="SAML_DOMAIN" />.</translation> -<translation id="7268365133021434339">Uždaryti skirtukus</translation> <translation id="7268659760406822741">Prieinamos paslaugos</translation> <translation id="7270858098575133036">Paklausti, kai svetainė nori naudoti sistemos išskirtinius pranešimus MIDI įrenginiams pasiekti</translation> <translation id="7272674038937250585">Nepateikta jokių aprašų</translation> @@ -4242,7 +4232,6 @@ <translation id="7576032389798113292">6 x 4</translation> <translation id="7576690715254076113">Gretinti</translation> <translation id="7576976045740938453">Iškilo su demonstracinio režimo paskyra susijusi problema.</translation> -<translation id="7579149537961810247">Nutildyti svetaines</translation> <translation id="7580671184200851182">Paleisti tą patį garso įrašą visuose garsiakalbiuose (monofoninio garso įrašas)</translation> <translation id="7581462281756524039">Valymo įrankis</translation> <translation id="7582582252461552277">Rinktis šį tinklą</translation> @@ -4596,7 +4585,6 @@ <translation id="8068253693380742035">Palieskite, kad prisijungtumėte</translation> <translation id="8069615408251337349">„Google“ spausdinimas iš debesies</translation> <translation id="8071432093239591881">Spausdinti kaip vaizdą</translation> -<translation id="8072988827236813198">Prisegti skirtukus</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Programos duomenys gali būti bet kokie programos išsaugoti duomenys (atsižvelgiant į kūrėjo nustatymus), įskaitant kontaktus, pranešimus ir nuotraukas.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Atsarginės kopijos duomenys nebus įtraukti skaičiuojant Disko saugyklos kvotą.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Šią paslaugą galite išjungti skiltyje „Nustatymai“.<ph name="END_PARAGRAPH3" /></translation> @@ -4782,7 +4770,6 @@ <translation id="8368859634510605990">&Atidaryti visas žymes</translation> <translation id="8371695176452482769">Kalbėti dabar</translation> <translation id="8372369524088641025">Netinkamas WEP raktas</translation> -<translation id="8373553483208508744">Nutildyti skirtukų garsą</translation> <translation id="8378714024927312812">Tvarko jūsų organizacija</translation> <translation id="8379878387931047019">Šis įrenginys nepalaiko saugos rakto, kurio reikalaujama šioje svetainėje, tipo</translation> <translation id="8382913212082956454">Kopijuoti &el. pašto adresą</translation> @@ -4890,7 +4877,6 @@ <translation id="8546930481464505581">Tinkinti lietimo juostą</translation> <translation id="8547013269961688403">Įgalinti viso ekrano didintuvą</translation> <translation id="85486688517848470">Laikykite paspaustą paieškos klavišą, kad perjungtumėte viršutinės eilutės klavišų veikimą</translation> -<translation id="855081842937141170">Pažymėti skirtuką</translation> <translation id="8551388862522347954">Licencijos</translation> <translation id="8553342806078037065">Tvarkyti kitus žmones</translation> <translation id="8554899698005018844">Kalbos nėra</translation> @@ -4920,6 +4906,7 @@ <translation id="8598453409908276158">Ne „smėlio dėžės“ papildinys užblokuotas</translation> <translation id="8601206103050338563">TLS WWW kliento tapatybės nustatymas</translation> <translation id="8602851771975208551">Kita jūsų kompiuteryje esanti programa pridėjo programą, kuri gali pakeisti „Chrome“ veikimo būdą.</translation> +<translation id="8604763363205185560">Padėkite tobulinti naršyklę „Chrome“ ir jos našumą</translation> <translation id="8605428685123651449">„SQLite“ atmintis</translation> <translation id="8606726445206553943">Naudoti MIDI įrenginius</translation> <translation id="8609465669617005112">Perkelti į viršų</translation> @@ -5204,7 +5191,6 @@ <translation id="9038430547971207796">Kitą kartą telefonu bus galima atrakinti „<ph name="DEVICE_TYPE" />“. Funkciją „Smart Lock“ galite išjungti „Nustatymų“ skiltyje.</translation> <translation id="9038649477754266430">Naudokite numatymo paslaugą, kad puslapiai būtų įkeliami greičiau</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Nutildyti skirtukų garsą</translation> <translation id="9040661932550800571">Atnaujinti <ph name="ORIGIN" /> slaptažodį?</translation> <translation id="9041692268811217999">Administratorius neleidžia prieigos prie vietinių failų įrenginyje</translation> <translation id="9042893549633094279">Privatumas ir sauga</translation> @@ -5302,7 +5288,6 @@ <translation id="920045321358709304">Ieškoti sistemoje „<ph name="SEARCH_ENGINE" />“</translation> <translation id="9201220332032049474">Ekrano užrakto parinktys</translation> <translation id="9203398526606335860">&Profiliavimas įgalintas</translation> -<translation id="9203478404496196495">Įjungti garsą skirtuke</translation> <translation id="9203904171912129171">Pasirinkti įrenginį</translation> <translation id="9203962528777363226">Šio įrenginio administratorius neleido pridėti naujų naudotojų</translation> <translation id="9213073329713032541">Diegimas sėkmingai pradėtas.</translation>
diff --git a/chrome/app/resources/generated_resources_lv.xtb b/chrome/app/resources/generated_resources_lv.xtb index 531d063..0a0886ba 100644 --- a/chrome/app/resources/generated_resources_lv.xtb +++ b/chrome/app/resources/generated_resources_lv.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Nospiediet ESCAPE, lai izlaistu (tikai neoficiāli būvējumi).</translation> <translation id="1093457606523402488">Redzamie tīkli:</translation> <translation id="1094607894174825014">Tālāk minētajā ierīcē tika pieprasīta lasīšanas vai rakstīšanas darbība ar nederīgu nobīdi: “<ph name="DEVICE_NAME" />”.</translation> -<translation id="109758035718544977">Rādīt vietnes</translation> <translation id="1097658378307015415">Pirms pierakstāties, uzsāciet viesa sesiju, lai aktivizētu tīklu <ph name="NETWORK_ID" />.</translation> <translation id="1103523840287552314">Vienmēr tulkot <ph name="LANGUAGE" /> valodas saturu</translation> <translation id="1108600514891325577">&Apturēt</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Pārlūkojiet tīmekli inkognito režīma logā, nesaglabājot pārlūkošanas vēsturi.</translation> <translation id="1213037489357051291">Ir iestatīti pirkstu nospiedumi (<ph name="NUM_FINGERPRINTS" />)</translation> <translation id="1215411991991485844">Pievienota jauna fona lietotne</translation> -<translation id="1216654534877302979">Nerādīt vietnes</translation> <translation id="1216659994753476700">Diemžēl mēs nevaram piekļūt jūsu profilam. Šajā ierīcē glabātie faili un dati, iespējams, ir zaudēti.<ph name="BR" /> <ph name="BR" /> Jums būs vēlreiz jāizveido profils.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Saglabāt datus jūsu Google diska kontā</translation> <translation id="1288037062697528143">Nakts režīms tiks automātiski ieslēgts saulrietā.</translation> <translation id="1288300545283011870">Runas rekvizīti</translation> -<translation id="1293177648337752319">Rādīt vietni</translation> <translation id="1293264513303784526">USB-C ierīce (pieslēgvieta pa kreisi)</translation> <translation id="1293556467332435079">Faili</translation> <translation id="1296497012903089238">Sertifikāta veids</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Sākumlapa ir jaunas cilnes lapa</translation> <translation id="1436671784520050284">Turpināt iestatīšanu</translation> <translation id="1436784010935106834">Noņemts</translation> -<translation id="1438632560381091872">Ieslēgt ciļņu skaņu</translation> <translation id="1442392616396121389">Maršrutēšanas prefikss</translation> <translation id="144283815522798837">Atlasīti: <ph name="NUMBER_OF_ITEMS_SELECTED" /></translation> <translation id="1444628761356461360">Šo iestatījumu pārvalda ierīces īpašnieks <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Kopš pēdējās reizes, kad ievadījāt paroli, ir pievienota cita tastatūra. Tā, iespējams, mēģina piesavināties jūsu taustiņsitienus.</translation> <translation id="1567750922576943685">Identitātes apstiprināšana palīdz aizsargāt jūsu personas informāciju</translation> <translation id="1567993339577891801">JavaScript konsole</translation> -<translation id="1568067597247500137">Nerādīt vietni</translation> <translation id="1568323446248056064">Atvērt attēlojuma ierīces iestatījumus</translation> <translation id="1572266655485775982">Iespējot Wi-Fi</translation> <translation id="1572585716423026576">Iestatīt kā fona tapeti</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">X9.62 ECDSA paraksts ar SHA-1</translation> <translation id="1644574205037202324">Vēsture</translation> <translation id="1645516838734033527">Lai Smart Lock varētu saglabāt jūsu ierīces (<ph name="DEVICE_TYPE" />) drošību, tālrunī jāiestata ekrāna bloķēšana.</translation> -<translation id="1646102270785326155">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. $1 joprojām varēs pierakstīties vēlāk.</translation> <translation id="1646982517418478057">Lūdzu, ievadiet paroli, lai šifrētu šo sertifikātu</translation> <translation id="164814987133974965">Uzraudzīts lietotājs var pārlūkot tīmekli ar jūsu palīdzību. Kā uzraudzīta lietotāja pārzinis varat: <ph name="BEGIN_BOLD" />ļaut vai aizliegt<ph name="END_BOLD" /> noteiktu vietņu skatīšanu; @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Tas nosaka arī to, kāda lapa tiks rādīta, kad meklēsiet, izmantojot universālo lodziņu.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Lai noņemtu lietotnes, pārejiet uz sadaļu Iestatījumi > Google Play veikals > Pārvaldīt Android preferences > Lietotnes vai Lietojumprogrammu pārvaldnieks. Pēc tam pieskarieties lietotnei, kuru vēlaties atinstalēt (iespējams, būs jāvelk pa labi vai pa kreisi, lai atrastu lietotni). Pēc tam pieskarieties vienumam Atinstalēt vai Atspējot.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Notiek pieprasījuma sūtīšana...</translation> -<translation id="1732215134274276513">Atspraust cilnes</translation> <translation id="1733383495376208985">Šifrējiet sinhronizētos datus, izmantojot savu <ph name="BEGIN_LINK" />sinhronizācijas ieejas frāzi<ph name="END_LINK" />. Tajā nav iekļauti maksājumu veidi un adreses no pakalpojuma Google Pay.</translation> <translation id="1734824808160898225">Pārlūka <ph name="PRODUCT_NAME" /> automātiskā atjaunināšana, iespējams, nebūs pieejama.</translation> <translation id="1736419249208073774">Izpētīt</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Visi faili</translation> <translation id="1809734401532861917">Pievienot manas grāmatzīmes, vēsturi, paroles un citus iestatījumus kontam <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Priekšskatījums nav pieejams</translation> -<translation id="1812631533912615985">Atspraust cilnes</translation> <translation id="1813278315230285598">Pakalpojumi</translation> <translation id="18139523105317219">EDI puses nosaukums</translation> <translation id="1815083418640426271">Ielīmēt kā vienkāršu tekstu</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Pārlūkprogramma Chrome tiek kontrolēta, izmantojot automatizētas pārbaudes programmatūru.</translation> <translation id="2070909990982335904">Nosaukumi, kas sākas ar punktu, tiek rezervēti sistēmai. Izvēlieties citu nosaukumu.</translation> <translation id="2071393345806050157">Nav lokālā žurnālfaila.</translation> -<translation id="2074527029802029717">Atspraust cilni</translation> <translation id="2075474481720804517">Akumulators: <ph name="BATTERY_PERCENTAGE" />%</translation> <translation id="2075959085554270910">Ļauj iespējot vai atspējot funkciju “Pieskarties, lai noklikšķinātu” un vilkšanu pieskaroties</translation> <translation id="2076269580855484719">Slēpt šo spraudni</translation> @@ -1352,7 +1343,6 @@ <translation id="3045447014237878114">Šajā vietnē tika automātiski lejupielādēti vairāki faili</translation> <translation id="3046910703532196514">Tīmekļa lapa, pabeigta</translation> <translation id="304747341537320566">Runas programmas</translation> -<translation id="304826556400666995">Ieslēgt ciļņu skaņu</translation> <translation id="3053013834507634016">Sertifikāta atslēgas lietošana</translation> <translation id="3057861065630527966">Dublēt fotoattēlus un videoklipus</translation> <translation id="3060379269883947824">Iespējot funkciju “Atlasīt, lai izrunātu”</translation> @@ -2335,7 +2325,6 @@ <translation id="4628762811416793313">Linux konteinera iestatīšana netika pabeigta. Lūdzu, mēģiniet vēlreiz.</translation> <translation id="4628948037717959914">Fotoattēls</translation> <translation id="4631887759990505102">Izpildītājs</translation> -<translation id="4632483769545853758">Ieslēgt cilnes skaņu</translation> <translation id="4633003931260532286">Paplašinājumam ir nepieciešama “<ph name="IMPORT_NAME" />” versija <ph name="IMPORT_VERSION" /> (vismaz), taču ir instalēta tikai versija <ph name="INSTALLED_VERSION" />.</translation> <translation id="4634771451598206121">Pierakstīties vēlreiz...</translation> <translation id="4635398712689569051">Lapa “<ph name="PAGE_NAME" />” nav pieejama viesa režīma lietotājiem.</translation> @@ -2399,7 +2388,6 @@ <translation id="4735803855089279419">Sistēmā neizdevās noteikt šīs ierīces identifikatorus.</translation> <translation id="4737715515457435632">Lūdzu, izveidojiet savienojumu ar tīklu</translation> <translation id="473775607612524610">Atjaunināt</translation> -<translation id="474217410105706308">Izslēgt cilnes skaņu</translation> <translation id="4742746985488890273">Piespraust plauktam</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Uzzināt, kā atjaunināt lietojumprogrammas<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Messages</translation> @@ -2624,7 +2612,6 @@ <translation id="5094721898978802975">Sazināties ar iebūvētām lietojumprogrammām, kas sadarbojas</translation> <translation id="5097002363526479830">Neizdevās izveidot savienojumu ar tīklu <ph name="NAME" />: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Atvērt visas grāmatzīmes</translation> -<translation id="5105855035535475848">Saistītas cilnes</translation> <translation id="5108967062857032718">Iestatījumi — Android lietotņu noņemšana</translation> <translation id="5109044022078737958">Atlēte</translation> <translation id="5111692334209731439">Grāmat&zīmju pārvaldnieks</translation> @@ -2689,7 +2676,6 @@ <translation id="520621735928254154">Sertifikāta importēšanas kļūda</translation> <translation id="5209320130288484488">Ierīces nav atrastas</translation> <translation id="5209518306177824490">SHA-1 pirkstu nospiedums</translation> -<translation id="5210365745912300556">Aizvērt cilni</translation> <translation id="5213481667492808996">Jūsu <ph name="NAME" /> datu pakalpojums ir gatavs lietošanai</translation> <translation id="5213891612754844763">Rādīt starpniekservera iestatījumus</translation> <translation id="521582610500777512">Fotoattēls tika noraidīts.</translation> @@ -2740,7 +2726,6 @@ <translation id="5270167208902136840">Rādīt citas lietotnes (vēl <ph name="NUMBER_OF_MORE_APPS" />)</translation> <translation id="5275352920323889391">Suns</translation> <translation id="5275973617553375938">No Google diska atkoptie faili</translation> -<translation id="527605719918376753">Izslēgt cilnes skaņu</translation> <translation id="527605982717517565">Vienmēr atļaut izmantot JavaScript vietnē <ph name="HOST" /></translation> <translation id="5280426389926346830">Vai izveidot saīsni?</translation> <translation id="528208740344463258">Lai lejupielādētu un izmantotu Android lietotnes, vispirms instalējiet nepieciešamo atjauninājumu. Kamēr <ph name="DEVICE_TYPE" /> ierīce tiek atjaunināta, to nevar izmantot. Pēc instalēšanas pabeigšanas <ph name="DEVICE_TYPE" /> ierīce tiks restartēta.</translation> @@ -2863,7 +2848,6 @@ <translation id="5449551289610225147">Parole nav derīga.</translation> <translation id="5449588825071916739">Saglabāt visas cilnes kā grāmatzīmes</translation> <translation id="5449716055534515760">Aizvērt Win&dow</translation> -<translation id="5453029940327926427">Aizvērt cilnes</translation> <translation id="5454166040603940656">izmantojot <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Nav derīgi</translation> <translation id="5457459357461771897">Lasīt un dzēst fotoattēlus, mūziku un citu datorā esošu multivides saturu</translation> @@ -3328,7 +3312,6 @@ <translation id="6122875415561139701">Rakstīšanas darbība nav atļauta šajā ierīcē: “<ph name="DEVICE_NAME" />”.</translation> <translation id="6124650939968185064">Tālāk norādītie paplašinājumi ir atkarīgi no šī paplašinājuma:</translation> <translation id="6125479973208104919">Diemžēl jums būs atkārtoti jāpievieno savs konts šajā <ph name="DEVICE_TYPE" /> ierīcē.</translation> -<translation id="612596694132302162">Rādīt vietni</translation> <translation id="6129691635767514872">Atlasītie dati ir noņemti no pārlūka Chrome un sinhronizētajām ierīcēm. Jūsu Google kontam vietnē <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> var būt cita veida pārlūkošanas vēstures dati, piemēram, meklēšanas vaicājumi un darbības citos Google pakalpojumos.</translation> <translation id="6129938384427316298">Netscape sertifikāta komentārs</translation> <translation id="6129953537138746214">Atstarpe</translation> @@ -3531,7 +3514,6 @@ <translation id="6436164536244065364">Skatiet interneta veikalā</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> — audio atskaņošana</translation> <translation id="6442187272350399447">Smaidiņš</translation> -<translation id="6442697326824312960">Atcelt cilnes piespraušanu</translation> <translation id="6444070574980481588">Datuma un laika iestatīšana</translation> <translation id="6445450263907939268">Ja nevēlējāties veikt šīs izmaiņas, varat atjaunot iepriekšējos iestatījumus.</translation> <translation id="6447842834002726250">Sīkfaili</translation> @@ -3734,7 +3716,6 @@ <translation id="6770664076092644100">Apstiprināt, izmantojot NFC</translation> <translation id="6771503742377376720">Ir sertifikāta izdevējiestāde</translation> <translation id="6777817260680419853">Novirzīšana bloķēta</translation> -<translation id="6778959797435875428">Rādīt vietnes</translation> <translation id="677965093459947883">Ļoti mazs</translation> <translation id="6780439250949340171">pārvaldīt citus iestatījumus.</translation> <translation id="6781284683813954823">Saite uz svētku logotipu</translation> @@ -4051,7 +4032,6 @@ <translation id="7257666756905341374">Lasīt datus, ko kopējat un ielīmējat</translation> <translation id="7258697411818564379">Jūsu PIN ir pievienots</translation> <translation id="7262004276116528033">Šo pierakstīšanās pakalpojumu nodrošina <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Aizvērt cilnes</translation> <translation id="7268659760406822741">Pieejamie pakalpojumi</translation> <translation id="7270858098575133036">Jautāt, ja vietnē tiek mēģināts izmantot ekskluzīvus sistēmas ziņojumus, lai piekļūtu MIDI ierīcēm</translation> <translation id="7272674038937250585">Apraksts nav sniegts.</translation> @@ -4241,7 +4221,6 @@ <translation id="7576032389798113292">6 x 4</translation> <translation id="7576690715254076113">Kārtot</translation> <translation id="7576976045740938453">Radās problēma ar demonstrācijas režīma kontu.</translation> -<translation id="7579149537961810247">Nerādīt vietnes</translation> <translation id="7580671184200851182">Atskaņot to pašu audio saturu visos skaļruņos (mono audio)</translation> <translation id="7581462281756524039">Tīrīšanas rīks</translation> <translation id="7582582252461552277">Dot priekšroku šim tīklam</translation> @@ -4594,7 +4573,6 @@ <translation id="8068253693380742035">Pieskarieties, lai pierakstītos</translation> <translation id="8069615408251337349">Google mākoņdruka</translation> <translation id="8071432093239591881">Drukāt kā attēlu</translation> -<translation id="8072988827236813198">Saistītas cilnes</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Lietotņu dati var būt jebkādi lietotņu saglabātie dati (atkarībā no izstrādātāja iestatījumiem), tostarp tādi dati kā kontaktpersonas, ziņojumi un fotoattēli.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Dublētie dati netiek ieskaitīti jūsu bērna Diska krātuves kvotā.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Šo pakalpojumu varat izslēgt sadaļā Iestatījumi.<ph name="END_PARAGRAPH3" /></translation> @@ -4781,7 +4759,6 @@ <translation id="8368859634510605990">&Atvērt visas grāmatzīmes</translation> <translation id="8371695176452482769">Runājiet tūlīt</translation> <translation id="8372369524088641025">Neatbilstoša WEP atslēga</translation> -<translation id="8373553483208508744">Izslēgt ciļņu skaņu</translation> <translation id="8378714024927312812">Pārvalda jūsu organizācija</translation> <translation id="8379878387931047019">Šī ierīce neatbalsta vietnes pieprasītās drošības atslēgas veidu.</translation> <translation id="8382913212082956454">Kopēt un nosūtīt adresi pa e-pastu</translation> @@ -4889,7 +4866,6 @@ <translation id="8546930481464505581">Pielāgot skārienjoslu</translation> <translation id="8547013269961688403">Iespējot pilnekrāna lupu</translation> <translation id="85486688517848470">Turiet meklēšanas taustiņu, lai pārslēgtu augšējās rindas taustiņu funkcijas.</translation> -<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> @@ -5203,7 +5179,6 @@ <translation id="9038430547971207796">Nākamajā reizē šīs ierīces (<ph name="DEVICE_TYPE" />) atbloķēšanai tiks izmantots jūsu tālrunis. Iestatījumos varat izslēgt Smart Lock.</translation> <translation id="9038649477754266430">Ieteikumu pakalpojuma izmantošana ātrākai lapu ielādei</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Izslēgt ciļņu skaņu</translation> <translation id="9040661932550800571">Vai atjaunināt paroli vietnei <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Administrators ir atspējojis piekļuvi lokālajiem failiem jūsu datorā.</translation> <translation id="9042893549633094279">Konfidencialitāte un drošība</translation> @@ -5301,7 +5276,6 @@ <translation id="920045321358709304">Meklēt pakalpojumā <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Ekrāna bloķēšanas opcijas</translation> <translation id="9203398526606335860">&Profilēšana iespējota</translation> -<translation id="9203478404496196495">Ieslēgt cilnes skaņu</translation> <translation id="9203904171912129171">Atlasiet ierīci</translation> <translation id="9203962528777363226">Šīs ierīces administrators ir atspējojis jaunu lietotāju pievienošanu.</translation> <translation id="9213073329713032541">Instalēšana sekmīgi sākta.</translation>
diff --git a/chrome/app/resources/generated_resources_ml.xtb b/chrome/app/resources/generated_resources_ml.xtb index e3f0951..8bc9f19 100644 --- a/chrome/app/resources/generated_resources_ml.xtb +++ b/chrome/app/resources/generated_resources_ml.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">ഒഴിവാക്കുന്നതിനായി ESCAPE അമർത്തുക (അനൗദ്യോഗിക നിർമ്മിതകൾക്ക് മാത്രം).</translation> <translation id="1093457606523402488">ദൃശ്യമാകുന്ന നെറ്റ്വർക്കുകൾ:</translation> <translation id="1094607894174825014">അസാധുവായ ഒരു ഓഫ്സെറ്റ് ഉപയോഗിച്ചാണ് എഴുതുക അല്ലെങ്കിൽ വായിക്കുക പ്രവർത്തനം അഭ്യർത്ഥിച്ചത്: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">സൈറ്റുകൾ അൺമ്യൂട്ട് ചെയ്യുക</translation> <translation id="1097658378307015415">സൈൻ ഇൻ ചെയ്യുന്നതിന് മുമ്പ്, <ph name="NETWORK_ID" /> സജീവമാക്കാൻ അതിഥിയായി പ്രവേശിക്കുക</translation> <translation id="1103523840287552314"><ph name="LANGUAGE" /> എല്ലായ്പ്പോഴും വിവര്ത്തനം ചെയ്യുക </translation> <translation id="1108600514891325577">&നിറുത്തുക</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">അദൃശ്യ വിൻഡോ ഉപയോഗിച്ച്, നിങ്ങളുടെ ബ്രൗസിംഗ് ചരിത്രം സംരക്ഷിക്കാതെ, വെബ് ഉപയോഗിക്കുക</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> വിരലടയാളങ്ങൾ സജ്ജമാക്കി</translation> <translation id="1215411991991485844">പുതിയ പശ്ചാത്തല അപ്ലിക്കേഷൻ ചേർത്തു</translation> -<translation id="1216654534877302979">സൈറ്റുകൾ മ്യൂട്ട് ചെയ്യുക</translation> <translation id="1216659994753476700">ക്ഷമിക്കണം. ഞങ്ങൾക്ക് നിങ്ങളുടെ പ്രൊഫൈൽ ആക്സസ്സ് ചെയ്യാനാകുന്നില്ല. ഈ ഉപകരണത്തിൽ സംഭരിച്ച നിങ്ങളുടെ ഫയലുകളും വിവരങ്ങളും നഷ്ടപ്പെട്ടിരിക്കാം.<ph name="BR" /> <ph name="BR" /> നിങ്ങളുടെ പ്രൊഫൈൽ വീണ്ടും സജ്ജമാക്കേണ്ടതുണ്ട്.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">നിങ്ങളുടെ Google ഡ്രൈവ് അക്കൗണ്ടിൽ ഡാറ്റ സംഭരിക്കുക</translation> <translation id="1288037062697528143">സൂര്യാസ്തമയ സമയത്ത് നൈറ്റ് ലൈറ്റ് സ്വമേധയാ ഓണാകും</translation> <translation id="1288300545283011870">സംഭാഷണ പ്രോപ്പർട്ടികൾ</translation> -<translation id="1293177648337752319">സൈറ്റ് അൺമ്യൂട്ട് ചെയ്യുക</translation> <translation id="1293264513303784526">USB-C ഉപകരണം (ഇടത് പോർട്ട്)</translation> <translation id="1293556467332435079">ഫയലുകള്</translation> <translation id="1296497012903089238">സർട്ടിഫിക്കറ്റ് തരം</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">ഹോംപേജ് പുതിയ ടാബ് പേജാണ്</translation> <translation id="1436671784520050284">സജ്ജീകരിക്കുന്നത് തുടരുക</translation> <translation id="1436784010935106834">നീക്കംചെയ്തു</translation> -<translation id="1438632560381091872">ടാബുകൾ അൺമ്യൂട്ട് ചെയ്യുക</translation> <translation id="1442392616396121389">റൂട്ടിംഗ് പ്രിഫിക്സ്</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> തിരഞ്ഞെടുത്തു</translation> <translation id="1444628761356461360">ഈ ക്രമീകരണം നിയന്ത്രിക്കുന്നത്, ഉപകരണത്തിന്റെ ഉടമയായ <ph name="OWNER_EMAIL" /> ആണ്.</translation> @@ -385,7 +381,6 @@ <translation id="1567387640189251553">നിങ്ങൾ അവസാനം പാസ്വേഡ് നൽകിയത് മുതൽ ഒരു വ്യത്യസ്ത കീബോഡ് കണക്റ്റ് ചെയ്തിട്ടുണ്ട്. ഇത് നിങ്ങളുടെ കീസ്ട്രോക്കുകൾ മോഷ്ടിക്കാൻ ശ്രമിച്ചേക്കാം.</translation> <translation id="1567750922576943685">ഐഡൻറിറ്റി പരിശോധിച്ചുറപ്പിക്കുന്നത്, നിങ്ങളുടെ വ്യക്തിഗത വിവരം പരിരക്ഷിക്കാൻ സഹായിക്കുന്നു</translation> <translation id="1567993339577891801">JavaScript കണ്സോള്</translation> -<translation id="1568067597247500137">സൈറ്റ് മ്യൂട്ട് ചെയ്യുക</translation> <translation id="1568323446248056064">ഡിസ്പ്ലേ ഉപകരണ ക്രമീകരണം തുറക്കുക</translation> <translation id="1572266655485775982">Wi-Fi പ്രവർത്തനക്ഷമമാക്കൽ</translation> <translation id="1572585716423026576">വാൾപേപ്പറായി സജ്ജീകരിക്കുക</translation> @@ -437,7 +432,6 @@ <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="1646982517418478057">ഈ സർട്ടിഫിക്കറ്റ് എൻക്രിപ്റ്റ് ചെയ്യാൻ ഒരു പാസ്വേഡ് നൽകുക</translation> <translation id="164814987133974965">ഒരു സൂപ്പർവൈസുചെയ്ത ഉപയോക്താവിന് നിങ്ങളുടെ മാർഗനിർദ്ദേശങ്ങളുടെ സഹായത്തോടെ വെബ് പര്യവേക്ഷണം ചെയ്യാനാകും. സൂപ്പർവൈസുചെയ്ത ഉപയോക്താവിന്റെ മാനേജർ എന്ന നിലയിൽ നിങ്ങൾക്ക് ഇനിപ്പറയുന്നവ ചെയ്യാനാകും ചില വെബ്സൈറ്റുകൾ <ph name="BEGIN_BOLD" />അനുവദിക്കാനോ നിരോധിക്കാനോ<ph name="END_BOLD" />, @@ -496,7 +490,6 @@ <translation id="1729533290416704613">നിങ്ങൾ ഓമ്നിബോക്സിൽ നിന്ന് തിരയുമ്പോൾ ദൃശ്യമാകുന്ന പേജും അത് നിയന്ത്രിയ്ക്കും.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />ആപ്പുകൾ നീക്കംചെയ്യാൻ, ക്രമീകരണം > Google Play സ്റ്റോർ > Android മുൻഗണനകൾ മാനേജ് ചെയ്യുക > ആപ്പുകൾ അല്ലെങ്കിൽ ആപ്പ് മാനേജർ എന്നതിലേക്ക് പോവുക. അൺ ഇൻസ്റ്റാൾ ചെയ്യാൻ ആഗ്രഹിക്കുന്ന ആപ്പിൽ ടാപ്പ് ചെയ്യുക (ആപ്പ് കണ്ടെത്താൻ വലത്തോട്ടോ ഇടത്തോട്ടോ സ്വൈപ്പ് ചെയ്യേണ്ടതായി വന്നേക്കാം). തുടർന്ന്, ഇൻസ്റ്റാൾ ചെയ്യുക എന്നതിലോ പ്രവർത്തനരഹിതമാക്കുക എന്നതിലോ ടാപ്പ് ചെയ്യുക.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">അഭ്യര്ത്ഥന അയയ്ക്കുന്നു...</translation> -<translation id="1732215134274276513">ടാബുകള് അണ്പിന്ചെയ്യുക </translation> <translation id="1733383495376208985">നിങ്ങളുടെ <ph name="BEGIN_LINK" />സമന്വയ പാസ്ഫ്രെയ്സ്<ph name="END_LINK" /> ഉപയോഗിച്ച്, സമന്വയിപ്പിച്ച ഡാറ്റ എൻക്രിപ്റ്റ് ചെയ്യുക. ഇതിൽ Google Pay-ൽ നിന്നുള്ള പേയ്മെന്റ് രീതികളും വിലാസങ്ങളും അടങ്ങുന്നില്ല.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" />-ന്, സ്വയം അപ്ഡേറ്റ് ചെയ്യാന് സാധിക്കുന്നില്ലായിരിക്കാം</translation> <translation id="1736419249208073774">അടുത്തറിയുക</translation> @@ -548,7 +541,6 @@ <translation id="1807938677607439181">എല്ലാ ഫയലുകളും</translation> <translation id="1809734401532861917"><ph name="USER_EMAIL_ADDRESS" /> ഇമെയിലിൽ എന്റെ ബുക്ക്മാർക്കുകളും ചരിത്രവും പാസ്വേഡുകളും മറ്റ് ക്രമീകരണവും ചേർക്കുക</translation> <translation id="1810764548349082891">പ്രിവ്യൂ ലഭ്യമല്ല</translation> -<translation id="1812631533912615985">ടാബുകള് അണ്പിന്ചെയ്യുക</translation> <translation id="1813278315230285598">സേവനങ്ങള്</translation> <translation id="18139523105317219">EDI പാര്ട്ടി നാമം</translation> <translation id="1815083418640426271">പ്ലെയിന് വാചകമായി ഒട്ടിക്കുക</translation> @@ -707,7 +699,6 @@ <translation id="2065405795449409761">ഓട്ടോമെറ്റുചെയ്ത ടെസ്റ്റ് സോഫ്റ്റ്വെയറാണ് Chrome നിയന്ത്രിക്കുന്നത്.</translation> <translation id="2070909990982335904">ഡോട്ടോട് കൂടി ആരംഭിക്കുന്ന പേരുകൾ സിസ്റ്റത്തിനായി കരുതി വച്ചിരിക്കുന്നു. മറ്റൊരു പേര് ദയവായി തിരഞ്ഞെടുക്കുക.</translation> <translation id="2071393345806050157">പ്രദേശിക ലോഗ് ഫയലൊന്നുമില്ല.</translation> -<translation id="2074527029802029717">ടാബ് അണ്പിന് ചെയ്യുക</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% ബാറ്ററി</translation> <translation id="2075959085554270910">'ക്ലിക്ക് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക', 'ടാപ്പ് ചെയ്ത് ഇഴയ്ക്കൽ' എന്നിവ പ്രവർത്തനക്ഷമമാക്കാൻ/പ്രവർത്തനരഹിതമാക്കാൻ നിങ്ങളെ അനുവദിക്കുന്നു</translation> <translation id="2076269580855484719">ഈ പ്ലഗിന് മറയ്ക്കുക</translation> @@ -1349,7 +1340,6 @@ <translation id="3045447014237878114">ഈ സൈറ്റ് ഒന്നിലധികം ഫയലുകൾ സ്വമേധയാ ഡൗൺലോഡ് ചെയ്തു</translation> <translation id="3046910703532196514">വെബ്പേജ്, പൂർണ്ണമായും</translation> <translation id="304747341537320566">സ്പീച്ച് എഞ്ചിനുകൾ</translation> -<translation id="304826556400666995">ടാബുകൾ അൺമ്യൂട്ട് ചെയ്യുക</translation> <translation id="3053013834507634016">സര്ട്ടിഫിക്കറ്റ് കീ ഉപയോഗം</translation> <translation id="3057861065630527966">നിങ്ങളുടെ ഫോട്ടോകളും വീഡിയോകളും ബാക്കപ്പുചെയ്യുക</translation> <translation id="3060379269883947824">'വായിച്ചുകേൾക്കാൻ തിരഞ്ഞെടുക്കുക' പ്രവർത്തനക്ഷമമാക്കുക</translation> @@ -2331,7 +2321,6 @@ <translation id="4628762811416793313">Linux കണ്ടെയ്നർ സജ്ജീകരണം പൂർത്തിയായില്ല. വീണ്ടും ശ്രമിക്കുക.</translation> <translation id="4628948037717959914">ഫോട്ടോ</translation> <translation id="4631887759990505102">ആര്ട്ടിസ്റ്റ്</translation> -<translation id="4632483769545853758">ടാബ് അൺമ്യൂട്ട് ചെയ്യുക</translation> <translation id="4633003931260532286">വിപുലീകരണത്തിന് "<ph name="IMPORT_VERSION" />" എന്ന പതിപ്പെങ്കിലുമുള്ള "<ph name="IMPORT_NAME" />" ആവശ്യമാണെങ്കിലും ""<ph name="INSTALLED_VERSION" />" പതിപ്പ് മാത്രം ഇൻസ്റ്റാൾ ചെയ്തിരിക്കുന്നു</translation> <translation id="4634771451598206121">വീണ്ടും പ്രവേശിക്കുക...</translation> <translation id="4635398712689569051">അതിഥി ഉപയോക്താക്കൾക്ക്, <ph name="PAGE_NAME" /> ലഭ്യമല്ല.</translation> @@ -2395,7 +2384,6 @@ <translation id="4735803855089279419">ഈ ഉപകരണത്തിനായി ഉപകരണ ഐഡന്റിഫയറുകൾ നിർണ്ണയിക്കാൻ സിസ്റ്റത്തിനായില്ല.</translation> <translation id="4737715515457435632">ഒരു നെറ്റ്വർക്കിലേക്ക് കണക്റ്റുചെയ്യുക</translation> <translation id="473775607612524610">അപ്ഡേറ്റുചെയ്യുക</translation> -<translation id="474217410105706308">ടാബ് മ്യൂട്ടുചെയ്യുക</translation> <translation id="4742746985488890273">ഷെൽഫിൽ പിൻ ചെയ്യുക</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />അപ്ലിക്കേഷനുകൾ അപ്ഡേറ്റ് ചെയ്യുന്നത് എങ്ങനെയെന്ന് അറിയുക<ph name="END_LINK" /></translation> <translation id="4746351372139058112">സന്ദേശങ്ങൾ</translation> @@ -2620,7 +2608,6 @@ <translation id="5094721898978802975">സഹകരിക്കുന്ന നേറ്റീവ് അപ്ലിക്കേഷനുകളുമായി ആശയവിനിമയം നടത്തുക</translation> <translation id="5097002363526479830">'<ph name="NAME" />' നെറ്റ്വര്ക്കിലേക്ക് ബന്ധിപ്പിക്കുന്നതിൽ പരാജയപ്പെട്ടു: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">എല്ലാ ബുക്മാര്ക്കുകളും തുറക്കുക</translation> -<translation id="5105855035535475848">ടാബുകള് കോര്ക്കുക</translation> <translation id="5108967062857032718">ക്രമീകരണം - Android ആപ്സ് നീക്കംചെയ്യുക</translation> <translation id="5109044022078737958">മിയ</translation> <translation id="5111692334209731439">&ബുക്ക്മാര്ക്ക് മാനേജര്</translation> @@ -2685,7 +2672,6 @@ <translation id="520621735928254154">സർട്ടിഫിക്കറ്റ് ഇമ്പോർട്ടുചെയ്യുന്നതിൽ പിശക്</translation> <translation id="5209320130288484488">ഉപകരണങ്ങളൊന്നും കണ്ടെത്തിയില്ല</translation> <translation id="5209518306177824490">SHA-1 ഫിംഗര്പ്രിന്റ്</translation> -<translation id="5210365745912300556">ടാബ് അടയ്ക്കൂ</translation> <translation id="5213481667492808996">നിങ്ങളുടെ '<ph name="NAME" />' ഡാറ്റാ സേവനം ഉപയോഗിക്കാൻ തയ്യാറാണ്</translation> <translation id="5213891612754844763">പ്രോക്സി ക്രമീകരണങ്ങൾ കാണിക്കുക</translation> <translation id="521582610500777512">ഫോട്ടോ നിരസിച്ചു</translation> @@ -2736,7 +2722,6 @@ <translation id="5270167208902136840"><ph name="NUMBER_OF_MORE_APPS" /> ആപ്പുകൾ കൂടി കാണിക്കുക</translation> <translation id="5275352920323889391">നായ</translation> <translation id="5275973617553375938">Google ഡ്രൈവിൽ നിന്നും ഫയലുകൾ വീണ്ടെടുത്തു</translation> -<translation id="527605719918376753">ടാബ് മ്യൂട്ടുചെയ്യുക</translation> <translation id="527605982717517565"><ph name="HOST" /> ല് എല്ലായ്പ്പോഴുംJavaScript അനുവദിക്കുക </translation> <translation id="5280426389926346830">കുറുക്കുവഴി സൃഷ്ടിക്കണോ?</translation> <translation id="528208740344463258">Android ആപ്പുകൾ ഡൗൺലോഡ് ചെയ്ത് ഉപയോഗിക്കാൻ ആദ്യം നിങ്ങൾ ഈ ആവശ്യമായ അപ്ഡേറ്റ് ഇൻസ്റ്റാൾ ചെയ്യേണ്ടതുണ്ട്. <ph name="DEVICE_TYPE" /> അപ്ഡേറ്റ് ചെയ്യുമ്പോൾ, നിങ്ങൾക്കത് ഉപയോഗിക്കാനാവില്ല. ഇൻസ്റ്റലേഷൻ പൂർത്തിയായി കഴിയുമ്പോൾ, നിങ്ങളുടെ <ph name="DEVICE_TYPE" /> പുനരാരംഭിക്കും.</translation> @@ -2859,7 +2844,6 @@ <translation id="5449551289610225147">അസാധുവായ പാസ്വേഡ്</translation> <translation id="5449588825071916739">എല്ലാ ടാബുകളും ബുക്ക്മാര്ക്ക് ചെയ്യുക</translation> <translation id="5449716055534515760">വി&ന്ഡോ അടയ്ക്കുക</translation> -<translation id="5453029940327926427">ടാബുകള് അടയ്ക്കുക</translation> <translation id="5454166040603940656"><ph name="PROVIDER" /> എന്നതിനൊപ്പം</translation> <translation id="5457113250005438886">അസാധുവാണ്</translation> <translation id="5457459357461771897">നിങ്ങളുടെ കമ്പ്യൂട്ടറിൽ നിന്ന് ഫോട്ടോകളും സംഗീതവും മറ്റ് മീഡിയയും റീഡുചെയ്യുക, ഇല്ലാതാക്കുക</translation> @@ -3326,7 +3310,6 @@ <translation id="6122875415561139701">ഇനി പറയുന്നതിൽ എഴുതാൻ അനുമതിയില്ല: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">ഇനിപ്പറയുന്ന വിപുലീകരണങ്ങൾ ഈ വിപുലീകരണത്തെ ആശ്രയിച്ചിരിക്കുന്നു:</translation> <translation id="6125479973208104919">നിർഭാഗ്യവശാൽ ഈ <ph name="DEVICE_TYPE" /> ഉപകരണത്തിൽ വീണ്ടും നിങ്ങളുടെ അക്കൗണ്ട് ചേർക്കേണ്ടതുണ്ട്.</translation> -<translation id="612596694132302162">സൈറ്റ് അൺമ്യൂട്ട് ചെയ്യുക</translation> <translation id="6129691635767514872">തിരഞ്ഞെടുത്ത ഡാറ്റയെ Chrome-ൽ നിന്നും സമന്വയിപ്പിച്ച ഉപകരണങ്ങളിൽ നിന്നും നീക്കം ചെയ്തു. നിങ്ങളുടെ Google അക്കൗണ്ടിന്, <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> എന്നതിൽ, മറ്റ് Google സേവനങ്ങളിൽ നിന്നുള്ള തിരയലുകളും ആക്റ്റിവിറ്റിയും എന്നിങ്ങനെ മറ്റ് തരത്തിലുള്ള ബ്രൗസിംഗ് ചരിത്രമുണ്ടായിരിക്കാം.</translation> <translation id="6129938384427316298">നെറ്റ്സ്കേപ്പ് സര്ട്ടിഫിക്കറ്റ് അഭിപ്രായം</translation> <translation id="6129953537138746214">സ്പെയ്സ്</translation> @@ -3529,7 +3512,6 @@ <translation id="6436164536244065364">വെബ് സ്റ്റോറിൽ കാണുക</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - ഓഡിയോ പ്ലേ ചെയ്യുന്നു</translation> <translation id="6442187272350399447">ആകര്ഷണീയമായ</translation> -<translation id="6442697326824312960">അണ്പിന് ടാബ്</translation> <translation id="6444070574980481588">തീയതിയും സമയവും സജ്ജമാക്കുക</translation> <translation id="6445450263907939268">ഈ മാറ്റങ്ങൾ ആവശ്യമില്ലെങ്കിൽ, നിങ്ങൾക്ക് മുമ്പത്തെ ക്രമീകരണങ്ങൾ പുനഃസ്ഥാപിക്കാം.</translation> <translation id="6447842834002726250">കുക്കികള്</translation> @@ -3733,7 +3715,6 @@ <translation id="6770664076092644100">NFC വഴി പരിശോധിച്ചുറപ്പിക്കുക</translation> <translation id="6771503742377376720">ഒരു സര്ട്ടിഫിക്കറ്റ് അതോറിറ്റി ആണ്</translation> <translation id="6777817260680419853">റീഡയറക്ട് ചെയ്യുന്നത് ബ്ലോക്ക് ചെയ്തു</translation> -<translation id="6778959797435875428">സൈറ്റുകൾ അൺമ്യൂട്ട് ചെയ്യുക</translation> <translation id="677965093459947883">വളരെ ചെറുത്</translation> <translation id="6780439250949340171">മറ്റ് ക്രമീകരണങ്ങൾ നിയന്ത്രിക്കുക</translation> <translation id="6781284683813954823">ഡൂഡ്ല് ലിങ്ക്</translation> @@ -4050,7 +4031,6 @@ <translation id="7257666756905341374">നിങ്ങൾ പകർത്തി ഒട്ടിച്ച ഡാറ്റ റീഡുചെയ്യുക</translation> <translation id="7258697411818564379">നിങ്ങളുടെ പിൻ ചേർത്തു</translation> <translation id="7262004276116528033">ഈ സൈൻ ഇൻ സേവനം ഹോസ്റ്റുചെയ്തിരിക്കുന്നത് <ph name="SAML_DOMAIN" /> ആണ്.</translation> -<translation id="7268365133021434339">ടാബുകള് അടയ്ക്കുക</translation> <translation id="7268659760406822741">ലഭ്യമായ സേവനങ്ങൾ</translation> <translation id="7270858098575133036">MIDI ഉപകരണങ്ങൾ ആക്സസ് ചെയ്യാൻ ഒരു സൈറ്റിന് സിസ്റ്റം എക്സ്ക്ലൂസീവ് സന്ദേശങ്ങൾ ഉപയോഗിക്കേണ്ട സാഹചര്യത്തിൽ അത് ആവശ്യപ്പെടുക</translation> <translation id="7272674038937250585">വിവരണമൊന്നും നൽകിയിട്ടില്ല</translation> @@ -4240,7 +4220,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">ഒത്തുനോക്കുക</translation> <translation id="7576976045740938453">ഡെമോ മോഡ് അക്കൗണ്ടിൽ ഒരു പ്രശ്നമുണ്ടായി.</translation> -<translation id="7579149537961810247">സൈറ്റുകൾ മ്യൂട്ട് ചെയ്യുക</translation> <translation id="7580671184200851182">എല്ലാ സ്പീക്കറുകളിലൂടെയും സമാനമായ ഓഡിയോ പ്ലേ ചെയ്യുക (മോണോ ഓഡിയോ)</translation> <translation id="7581462281756524039">ഒരു ക്ലീൻഅപ്പ് ഉപകരണം</translation> <translation id="7582582252461552277">ഈ നെറ്റ്വെർക്ക് തിരഞ്ഞെടുക്കുക</translation> @@ -4594,7 +4573,6 @@ <translation id="8068253693380742035">സൈൻ ഇൻ ചെയ്യാൻ സ്പർശിക്കുക</translation> <translation id="8069615408251337349">Google Cloud പ്രിന്റ്</translation> <translation id="8071432093239591881">ചിത്രമായി പ്രിന്റുചെയ്യുക</translation> -<translation id="8072988827236813198">ടാബുകള് കോര്ക്കുക</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />ആപ്പ് ഡാറ്റ എന്നത്, കോൺടാക്റ്റുകൾ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ എന്നിവ പോലെ രഹസ്യ സ്വഭാവമുള്ള ഡാറ്റ ഉൾപ്പെടെ ഒരു ആപ്പ് സംരക്ഷിച്ച (ഡെവലപ്പർ ക്രമീകരണം അടിസ്ഥാനമാക്കി) ഏത് ഡാറ്റയുമാകാം.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />ബാക്കപ്പ് ഡാറ്റ, നിങ്ങളുടെ കുട്ടിയുടെ ഡ്രൈവ് സ്റ്റോറേജിലെ ഇടം കുറയ്ക്കില്ല.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />നിങ്ങൾക്ക് ഈ സേവനം ക്രമീകരണത്തിൽ ഓഫാക്കാം.<ph name="END_PARAGRAPH3" /></translation> @@ -4780,7 +4758,6 @@ <translation id="8368859634510605990">എല്ലാ ബുക്ക്മാര്ക്കുകളും &തുറക്കുക</translation> <translation id="8371695176452482769">ഇപ്പോള് സംസാരിക്കുക</translation> <translation id="8372369524088641025">മോശം WEP കീ</translation> -<translation id="8373553483208508744">ടാബുകൾ മ്യൂട്ടുചെയ്യുക</translation> <translation id="8378714024927312812">നിങ്ങളുടെ സ്ഥാപനം മാനേജ് ചെയ്യുന്നത്</translation> <translation id="8379878387931047019">ഈ വെബ്സൈറ്റ് അഭ്യർത്ഥിച്ച തരത്തിലുള്ള സുരക്ഷാ കീ ഈ ഉപകരണം പിന്തുണയ്ക്കുന്നില്ല</translation> <translation id="8382913212082956454">ഇമെയില് വിലാസം& പകര്ത്തുക</translation> @@ -4888,7 +4865,6 @@ <translation id="8546930481464505581">'ടച്ച് ബാർ' ഇഷ്ടാനുസൃതമാക്കുക</translation> <translation id="8547013269961688403">പൂർണ്ണസ്ക്രീൻ മാഗ്നിഫയർ പ്രവർത്തനക്ഷമമാക്കുക</translation> <translation id="85486688517848470">മുകൾ-വരിയിലെ കീകളുടെ പ്രവർത്തനരീതി മാറ്റാൻ 'തിരയൽ' കീ അമർത്തിപ്പിടിക്കുക</translation> -<translation id="855081842937141170">ടാബ് പിൻ ചെയ്യുക</translation> <translation id="8551388862522347954">ലൈസന്സുകള്</translation> <translation id="8553342806078037065">മറ്റുള്ളവരെ മാനേജുചെയ്യുക</translation> <translation id="8554899698005018844">ഭാഷയില്ല</translation> @@ -5201,7 +5177,6 @@ <translation id="9038430547971207796">അടുത്ത തവണ, <ph name="DEVICE_TYPE" /> നിങ്ങളുടെ ഫോൺ അൺലോക്കുചെയ്യും. ക്രമീകരണത്തിൽ Smart Lock ഓഫാക്കാം.</translation> <translation id="9038649477754266430">പേജുകൾ കൂടുതൽ വേഗത്തിൽ ലോഡുചെയ്യാൻ ഒരു പ്രവചന സേവനം ഉപയോഗിക്കുക</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">ടാബുകൾ മ്യൂട്ടുചെയ്യുക</translation> <translation id="9040661932550800571"><ph name="ORIGIN" /> എന്നതിനായി പാസ്വേഡുകൾ അപ്ഡേറ്റ് ചെയ്യണോ?</translation> <translation id="9041692268811217999">അഡ്മിനിസ്ട്രേറ്റർ, നിങ്ങളുടെ മെഷീനിലുള്ള ലോക്കൽ ഫയലുകളിലേക്കുള്ള ആക്സസ്സ് പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു</translation> <translation id="9042893549633094279">സ്വകാര്യതയും സുരക്ഷയും</translation> @@ -5299,7 +5274,6 @@ <translation id="920045321358709304"><ph name="SEARCH_ENGINE" /> തിരയുക</translation> <translation id="9201220332032049474">സ്ക്രീൻ ലോക്ക് ഓപ്ഷനുകള്</translation> <translation id="9203398526606335860">&പ്രൊഫൈലിംഗ് പ്രാപ്തമാക്കി</translation> -<translation id="9203478404496196495">ടാബ് അൺമ്യൂട്ടുചെയ്യുക</translation> <translation id="9203904171912129171">ഒരു ഉപകരണം തിരഞ്ഞെടുക്കുക</translation> <translation id="9203962528777363226">പുതിയ ഉപയോക്താക്കളെ ചേരുന്നതിൽ നിന്ന് ഈ ഉപകരണത്തിന്റെ അഡ്മിനിസ്ട്രേറ്റർ അപ്രാപ്തമാക്കി</translation> <translation id="9213073329713032541">ഇൻസ്റ്റലേഷൻ ആരംഭിച്ചു.</translation>
diff --git a/chrome/app/resources/generated_resources_mr.xtb b/chrome/app/resources/generated_resources_mr.xtb index a2a2cdd..4d10ac6 100644 --- a/chrome/app/resources/generated_resources_mr.xtb +++ b/chrome/app/resources/generated_resources_mr.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">वगळण्यासाठी ESCAPE दाबा (केवळ अनाधिकृत बिल्डसाठी).</translation> <translation id="1093457606523402488">दृश्यमान नेटवर्क:</translation> <translation id="1094607894174825014">चुकीच्या ऑफसेटसह वाचा किंवा लिहा ऑपरेशनची यावर विनंती केली: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">साइट सशब्द करा</translation> <translation id="1097658378307015415">साइन इन करण्यापूर्वी, <ph name="NETWORK_ID" /> नेटवर्क सक्रिय करण्यासाठी कृपया अतिथी म्हणून प्रवेश करा.</translation> <translation id="1103523840287552314">नेहमी भाषांतर करा <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&थांबा</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">गुप्त विंडोसह तुमचा ब्राउझ करण्याचा इतिहास सेव्ह न करता वेब वापरा</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> फिंगरप्रिंट सेट केले</translation> <translation id="1215411991991485844">नवीन पार्श्वभूमी अॅप्लिकेशन जोडला</translation> -<translation id="1216654534877302979">साइट निःशब्द करा</translation> <translation id="1216659994753476700">आम्ही दिलगीर आहोत. आम्ही आपल्या प्रोफाईलमध्ये प्रवेश करू शकत नाही. या डिव्हाइसवर संचयित केलेल्या फायली आणि डेटा कदाचित गमावला जाऊ शकतो.<ph name="BR" /> <ph name="BR" /> तुम्हाला तुमचे प्रोफाईल पुन्हा सेट करावे लागेल.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">आपल्या Google ड्राइव्ह खात्यामध्ये डेटा संचयित करा</translation> <translation id="1288037062697528143">सूर्यास्ताच्या वेळी रात्रीचा प्रकाश आपोआप चालू होईल</translation> <translation id="1288300545283011870">स्पीच प्रॉपर्टी</translation> -<translation id="1293177648337752319">साइट सशब्द करा</translation> <translation id="1293264513303784526">USB-C डिव्हाइस (डावे पोर्ट)</translation> <translation id="1293556467332435079">फायली</translation> <translation id="1296497012903089238">सर्टिफिकेट प्रकार</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">होमपेज हे नवीन टॅब पृष्ठ आहे</translation> <translation id="1436671784520050284">सेटअप सुरू ठेवा</translation> <translation id="1436784010935106834">काढली</translation> -<translation id="1438632560381091872">टॅब सशब्द करा</translation> <translation id="1442392616396121389">मार्ग उपसर्ग</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> निवडले</translation> <translation id="1444628761356461360">ही सेटिंग डिव्हाइस मालक, <ph name="OWNER_EMAIL" /> द्वारे व्यवस्थापित केली आहे.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">तुम्ही शेवटचा पासवर्ड टाकल्या नंतर वेगळा कीबोर्ड कनेक्ट करण्यात आला आहे. तो कदाचित तुमचे कीस्ट्रोक चोरण्याचा प्रयत्न करत असेल.</translation> <translation id="1567750922576943685">तुमची ओळख पडताळल्याने तुमच्या वैयक्तिक माहितीचे संरक्षण करण्यात मदत होते</translation> <translation id="1567993339577891801">JavaScript कन्सोल</translation> -<translation id="1568067597247500137">साइट निःशब्द करा</translation> <translation id="1568323446248056064">डिस्प्ले डिव्हाइस सेटिंग्ज उघडा</translation> <translation id="1572266655485775982">वाय-फाय सक्षम</translation> <translation id="1572585716423026576">वॉलपेपर म्हणून सेट करा</translation> @@ -439,7 +434,6 @@ <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="1646982517418478057">कृपया हे प्रमाणपत्र एंक्रिप्ट करण्यासाठी एक पासवर्ड एंटर करा</translation> <translation id="164814987133974965">तुमच्या मार्गदर्शनाने एक पर्यवेक्षी वापरकर्ता वेब एक्सप्लोर करू शकतो. पर्यवेक्षी वापरकर्त्याचे व्यवस्थापक म्हणून, तुम्ही विशिष्ट वेबसाइट <ph name="BEGIN_BOLD" />अनुमत किंवा प्रतिबंधित<ph name="END_BOLD" /> करू शकता, @@ -498,7 +492,6 @@ <translation id="1729533290416704613">तुम्ही ओम्निबॉक्समधून शोध घेता तेव्हा कोणते पृष्ठ दर्शविले जाते हे देखील हे नियंत्रित करते.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />अॅप्स काढून टाकण्यासाठी, सेटिंग्ज > Google Play स्टोअर > Androआयडी प्राधान्ये व्यवस्थापित करा > अॅप्स किंवा अॅप्लिकेशन व्यवस्थापक यावर जा. नंतर तुम्हाला जे अॅप अनइंस्टॉल करायचे आहे त्यावर टॅप करा (अॅप शोधण्यासाठी तुम्हाला कदाचित उजवीकडे किंवा डावीकडे स्वाइप करावे लागेल). यानंतर अनइंस्टॉल करा किंवा बंद करा यावर टॅप करा.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">विनंती पाठवित आहे...</translation> -<translation id="1732215134274276513">टॅब अनपिन करा</translation> <translation id="1733383495376208985">तुमच्या स्वतःच्या <ph name="BEGIN_LINK" />सिंक पासफ्रेजसह<ph name="END_LINK" /> सिंक केलेला डेटा एंक्रिप्ट करा. यामध्ये Google Pay वरील पेमेंट पद्धतींचा आणि पत्त्यांचा समावेश नसतो.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> कदाचित अपडेट होत राहणार नाही</translation> <translation id="1736419249208073774">एक्सप्लोर करा</translation> @@ -550,7 +543,6 @@ <translation id="1807938677607439181">सर्व फायली</translation> <translation id="1809734401532861917">माझे बुकमार्क, इतिहास, पासवर्ड आणि अन्य सेटिंग्ज <ph name="USER_EMAIL_ADDRESS" /> मध्ये जोडा</translation> <translation id="1810764548349082891">कोणतेही पूर्वावलोकन उपलब्ध नाही</translation> -<translation id="1812631533912615985">टॅब अनपिन करा</translation> <translation id="1813278315230285598">सेवा</translation> <translation id="18139523105317219">EDI पार्टी नाव</translation> <translation id="1815083418640426271">साधा मजकूर म्हणून पेस्ट करा</translation> @@ -709,7 +701,6 @@ <translation id="2065405795449409761">स्वयंचलित चाचणी सॉफ्टवेअरने Chrome नियंत्रित केले जात आहे.</translation> <translation id="2070909990982335904">डॉटने प्रारंभ होणारी नावे सिस्टमसाठी आरक्षित आहेत. कृपया दुसरे नाव निवडा.</translation> <translation id="2071393345806050157">स्थानिक लॉग फाईल नाही.</translation> -<translation id="2074527029802029717">टॅब अनपिन करा</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% बॅटरी</translation> <translation id="2075959085554270910">क्लिक करण्यासाठी टॅप करा सुरू/बंद करण्याची आणि ड्रॅग करणे टॅप करण्याची तुम्हाला अनुमती देते</translation> <translation id="2076269580855484719">हे प्लगिन लपवा</translation> @@ -1351,7 +1342,6 @@ <translation id="3045447014237878114">या साइटने एकाहून अधिक फायली आपोआप डाउनलोड केल्या</translation> <translation id="3046910703532196514">वेबपृष्ठ, संपूर्ण</translation> <translation id="304747341537320566">स्पीच इंजिन</translation> -<translation id="304826556400666995">टॅब सशब्द करा</translation> <translation id="3053013834507634016">सर्टिफिकेट की वापर</translation> <translation id="3057861065630527966">तुमचे फोटो आणि व्हिडिओंचा बॅकअप घ्या</translation> <translation id="3060379269883947824">बोलण्यासाठी निवडा सुरू करा</translation> @@ -2334,7 +2324,6 @@ <translation id="4628762811416793313">Linux कंटेनर सेटअप पूर्ण झाला नाही. कृपया पुन्हा प्रयत्न करा.</translation> <translation id="4628948037717959914">फोटो</translation> <translation id="4631887759990505102">कलाकार</translation> -<translation id="4632483769545853758">टॅब सशब्द करा</translation> <translation id="4633003931260532286">एक्स्टेंशनला किमान आवृत्ती "<ph name="IMPORT_VERSION" />" सह "<ph name="IMPORT_NAME" />" ची गरज आहे, परंतु केवळ आवृत्ती "<ph name="INSTALLED_VERSION" />" इंस्टॉल केली गेली आहे</translation> <translation id="4634771451598206121">पुन्हा साइन इन करा...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> हे अतिथी वापरकर्त्यांसाठी उपलब्ध नाही.</translation> @@ -2398,7 +2387,6 @@ <translation id="4735803855089279419">सिस्टमला या डिव्हाइससाठी डिव्हाइस आयडेंटिफायर निर्धारित करता आला नाही.</translation> <translation id="4737715515457435632">कृपया एका नेटवर्कशी कनेक्ट करा</translation> <translation id="473775607612524610">अपडेट करा</translation> -<translation id="474217410105706308">टॅब निःशब्द करा</translation> <translation id="4742746985488890273">शेल्फवर पिन करा</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />अॅप्लिकेशन कशी अपडेट करायची ते शिका<ph name="END_LINK" /></translation> <translation id="4746351372139058112">संदेश</translation> @@ -2623,7 +2611,6 @@ <translation id="5094721898978802975">मूळ अनुप्रयोगांना सहकार्य करून संवाद प्रस्थापित करा</translation> <translation id="5097002363526479830">'<ph name="NAME" />': नेटवर्कशी कनेक्ट करण्यात अयशस्वी. <ph name="DETAILS" /></translation> <translation id="5101042277149003567">सर्व बुकमार्क उघडा</translation> -<translation id="5105855035535475848">पिन टॅब</translation> <translation id="5108967062857032718">सेटिंग्ज - Android अॅप्स काढून टाका</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">&बुकमार्क व्यवस्थापक</translation> @@ -2688,7 +2675,6 @@ <translation id="520621735928254154">सर्टिफिकेट आयात एरर</translation> <translation id="5209320130288484488">कोणतीही डिव्हाइसेस आढळली नाहीत</translation> <translation id="5209518306177824490">SHA-1 बोटाचा ठसा</translation> -<translation id="5210365745912300556">टॅब बंद करा</translation> <translation id="5213481667492808996">तुमची '<ph name="NAME" />' डेटा सेवा वापरण्यासाठी तयार आहे</translation> <translation id="5213891612754844763">प्रॉक्सी सेटिग्ज दर्शवा</translation> <translation id="521582610500777512">फोटो टाकून दिला</translation> @@ -2739,7 +2725,6 @@ <translation id="5270167208902136840">आणखी <ph name="NUMBER_OF_MORE_APPS" />अॅप्स दाखवा</translation> <translation id="5275352920323889391">कुत्रा</translation> <translation id="5275973617553375938">Google ड्राइव्ह वरून पुनर्प्राप्त केलेल्या फायली</translation> -<translation id="527605719918376753">टॅब नि:शब्द करा</translation> <translation id="527605982717517565"><ph name="HOST" /> वर JavaScript ला नेहमी परवानगी द्या</translation> <translation id="5280426389926346830">शॉर्टकट तयार करायचा?</translation> <translation id="528208740344463258">Android अॅप्स डाउनलोड करण्यासाठी आणि वापरण्यासाठी, तुम्ही हा आवश्यक अपडेट इंस्टॉल करणे गरजेचे आहे. तुमचे <ph name="DEVICE_TYPE" /> अपडेट होत असताना, तुम्ही त्याचा वापर करता आले नाही. इंस्टॉल झाल्यानंतर तुमचे <ph name="DEVICE_TYPE" /> रीस्टार्ट होईल.</translation> @@ -2862,7 +2847,6 @@ <translation id="5449551289610225147">चुकीचे पासवर्ड</translation> <translation id="5449588825071916739">सर्व टॅब बुकमार्क करा</translation> <translation id="5449716055534515760">विं&डो बंद करा</translation> -<translation id="5453029940327926427">टॅब बंद करा</translation> <translation id="5454166040603940656"><ph name="PROVIDER" /> सह</translation> <translation id="5457113250005438886">चुकीचा</translation> <translation id="5457459357461771897">आपल्या संगणकावरील फोटो, संगीत आणि अन्य मीडिया वाचा आणि हटवा</translation> @@ -3328,7 +3312,6 @@ <translation id="6122875415561139701">लिहा ऑपरेशनला यावर परवानगी नाही: " <ph name="DEVICE_NAME" /> ".</translation> <translation id="6124650939968185064">या विस्तारावर अवलंबून असलेले खालील विस्तार:</translation> <translation id="6125479973208104919">दुर्दैवाने, तुम्हाला या <ph name="DEVICE_TYPE" /> वर तुमचे खाते पुन्हा जोडावे लागेल.</translation> -<translation id="612596694132302162">साइट सशब्द करा</translation> <translation id="6129691635767514872">निवडलेला डेटा Chrome आणि सिंक केलेल्या डिव्हाइसमधून काढला गेला आहे. तुमच्या Google खात्यामध्ये Google च्या इतर सेवांमधील शोध आणि अॅक्टिव्हिटी यासारख्या ब्राउझिंग इतिहासाची इतर स्वरूपे <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> वर असू शकतात.</translation> <translation id="6129938384427316298">Netscape सर्टिफिकेट टिप्पणी</translation> <translation id="6129953537138746214">जागा</translation> @@ -3531,7 +3514,6 @@ <translation id="6436164536244065364">वेब स्टोअर मध्ये पहा</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - ऑडिओ प्ले करीत आहे</translation> <translation id="6442187272350399447">अप्रतिम</translation> -<translation id="6442697326824312960">टॅब अनपिन करा</translation> <translation id="6444070574980481588">तारीख आणि वेळ सेट करा</translation> <translation id="6445450263907939268">तुम्हाला हे बदल नको असल्यास, तुम्ही आपल्या मागील सेटिंग्ज पुनर्संचयित करू शकता.</translation> <translation id="6447842834002726250">कुकीज</translation> @@ -3734,7 +3716,6 @@ <translation id="6770664076092644100">NFC वापरून पडताळणी करा</translation> <translation id="6771503742377376720">एक प्रमाणन अधिकृतता आहे</translation> <translation id="6777817260680419853">रीडिरेक्ट ब्लॉक केले</translation> -<translation id="6778959797435875428">साइट सशब्द करा</translation> <translation id="677965093459947883">खूप लहान</translation> <translation id="6780439250949340171">अन्य सेटिंग्ज व्यवस्थापित करा</translation> <translation id="6781284683813954823">डूडल लिंक</translation> @@ -4051,7 +4032,6 @@ <translation id="7257666756905341374">तुम्ही कॉपी आणि पेस्ट करता तो डेटा वाचा</translation> <translation id="7258697411818564379">तुमचा पिन जोडला आहे</translation> <translation id="7262004276116528033">ही साइन-इन सेवा <ph name="SAML_DOMAIN" /> द्वारे होस्ट केली जाते</translation> -<translation id="7268365133021434339">टॅब बंद करा</translation> <translation id="7268659760406822741">उपलब्ध सेवा</translation> <translation id="7270858098575133036">MIDI डिव्हाइसमध्ये प्रवेश करण्यासाठी जेव्हा एखादी साइट सिस्टम अनन्य संदेश वापरू इच्छिते तेव्हा विचारा</translation> <translation id="7272674038937250585">वर्णन दिलेले नाही</translation> @@ -4241,7 +4221,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">तुलनात्मक</translation> <translation id="7576976045740938453">डेमो मोड खात्याला समस्या आली.</translation> -<translation id="7579149537961810247">साइट निःशब्द करा</translation> <translation id="7580671184200851182">सर्व स्पीकर मधून समान ऑडिओ प्ले करा (मोनो ऑडिओ)</translation> <translation id="7581462281756524039">एक क्लीनअप साधन</translation> <translation id="7582582252461552277">या नेटवर्कला प्राधान्य द्या</translation> @@ -4593,7 +4572,6 @@ <translation id="8068253693380742035">साइन इन साठी स्पर्श करा</translation> <translation id="8069615408251337349">Google क्लाउड प्रिंट</translation> <translation id="8071432093239591881">इमेज म्हणून प्रिंट करा</translation> -<translation id="8072988827236813198">पिन टॅब</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />अॅप डेटा म्हणजे अॅपने (डेव्हलपर सेटिंग्जवर आधारित) सेव्ह केलेला कोणताही डेटा असू शकतो , ज्यामध्ये संपर्क, मेसेज आणि फोटो यासारख्या डेटाचा समावेश आहे.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />बॅकअप डेटा तुमच्या लहान मुलाच्या ड्राइव्ह स्टोरेज कोट्यामध्ये गणला जाणार नाही.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />तुम्ही सेटिंग्जमध्ये ही सेवा बंद करू शकता.<ph name="END_PARAGRAPH3" /></translation> @@ -4779,7 +4757,6 @@ <translation id="8368859634510605990">सर्व बुकमार्क &उघडा</translation> <translation id="8371695176452482769">आता बोला</translation> <translation id="8372369524088641025">खराब WEP की</translation> -<translation id="8373553483208508744">टॅब निःशब्द करा</translation> <translation id="8378714024927312812">तुमच्या संस्थेकडून व्यवस्थापित केलेले</translation> <translation id="8379878387931047019">या वेबसाइटने विनंती केलेल्या सिक्युरिटी की च्या प्रकाराला हे डिव्हाइस सपोर्ट करत नाही</translation> <translation id="8382913212082956454">&ईमेल पत्ता कॉपी करा</translation> @@ -4887,7 +4864,6 @@ <translation id="8546930481464505581">स्पर्श बार कस्टमाइझ करा</translation> <translation id="8547013269961688403">क्षेत्रे भिंग सुरू करा</translation> <translation id="85486688517848470">शीर्ष-पंक्ती की चे वर्तन बदलण्यासाठी शोध की दाबून ठेवा</translation> -<translation id="855081842937141170">टॅब पिन करा</translation> <translation id="8551388862522347954">परवाने</translation> <translation id="8553342806078037065">इतर लोक व्यवस्थापित करा</translation> <translation id="8554899698005018844">कोणतीही भाषा नाही</translation> @@ -5202,7 +5178,6 @@ <translation id="9038430547971207796">पुढील वेळेस तुमचा फोन तुमचे <ph name="DEVICE_TYPE" /> अनलॉक करेल. सेटिंग्जमधून Smart Lock बंद करा.</translation> <translation id="9038649477754266430">पेज अधिक द्रुतपणे लोड करण्यासाठी पूर्वानुमान सेवेचा वापर करा</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">टॅब निःशब्द करा</translation> <translation id="9040661932550800571"><ph name="ORIGIN" /> साठी पासवर्ड अपडेट करायचा आहे का?</translation> <translation id="9041692268811217999">तुमच्या अॅडमिनिस्ट्रेटरने तुमच्या मशीनवरील स्थानिक फायलींचा अॅक्सेस बंद केला आहे</translation> <translation id="9042893549633094279">गोपनीयता आणि सुरक्षा</translation> @@ -5300,7 +5275,6 @@ <translation id="920045321358709304"><ph name="SEARCH_ENGINE" /> शोध</translation> <translation id="9201220332032049474">स्क्रीन लॉक पर्याय</translation> <translation id="9203398526606335860">&प्रोफाइलिंग सक्षम</translation> -<translation id="9203478404496196495">टॅब सशब्द करा</translation> <translation id="9203904171912129171">एक डिव्हाइस निवडा</translation> <translation id="9203962528777363226">या डिव्हाइसच्या प्रशासकाने नवीन वापरकर्त्यांना जोडले जाण्यापासून अक्षम केले आहे</translation> <translation id="9213073329713032541">इंस्टॉलेशनला यशस्वीरीत्या सुरुवात झाली.</translation>
diff --git a/chrome/app/resources/generated_resources_ms.xtb b/chrome/app/resources/generated_resources_ms.xtb index 05eaca61..ba01dff 100644 --- a/chrome/app/resources/generated_resources_ms.xtb +++ b/chrome/app/resources/generated_resources_ms.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Tekan ESCAPE untuk melangkau (Binaan tidak rasmi sahaja).</translation> <translation id="1093457606523402488">Rangkaian Kelihatan:</translation> <translation id="1094607894174825014">Pengendalian baca atau tulis diminta dengan ofset tidak sah pada: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">Nyahredam Tapak</translation> <translation id="1097658378307015415">Sebelum log masuk, sila masuk sebagai Tetamu untuk mengaktifkan rangkaian <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Sentiasa terjemahkan <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Berhenti</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Gunakan web tanpa menyimpan sejarah penyemakan imbas anda menggunakan tetingkap inkognito</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> cap jari disediakan</translation> <translation id="1215411991991485844">Apl latar belakang baharu ditambah</translation> -<translation id="1216654534877302979">Redam tapak</translation> <translation id="1216659994753476700">Kami memohon maaf. Kami tidak dapat mengakses profil anda. Fail dan data yang disimpan pada peranti ini mungkin telah hilang.<ph name="BR" /> <ph name="BR" /> Anda perlu menyediakan profil anda semula.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Simpan data dalam akaun Google Drive anda</translation> <translation id="1288037062697528143">Cahaya Malam akan dihidupkan secara automatik pada waktu matahari terbenam</translation> <translation id="1288300545283011870">Sifat Pertuturan</translation> -<translation id="1293177648337752319">Nyahredam Tapak</translation> <translation id="1293264513303784526">Peranti USB-C (port kiri)</translation> <translation id="1293556467332435079">Fail</translation> <translation id="1296497012903089238">Jenis Sijil</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Halaman utama ialah halaman Tab Baharu</translation> <translation id="1436671784520050284">Teruskan persediaan</translation> <translation id="1436784010935106834">Dibuang</translation> -<translation id="1438632560381091872">Nyahredam tab</translation> <translation id="1442392616396121389">Awalan penghalaan</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> dipilih</translation> <translation id="1444628761356461360">Tetapan ini diuruskan oleh pemilik peranti, <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Papan kekunci lain telah disambungkan sejak kali terakhir anda memasukkan kata laluan. Papan kekunci ini mungkin sedang cuba mencuri ketukan kekunci anda.</translation> <translation id="1567750922576943685">Pengesahan identiti anda dapat melindungi maklumat peribadi anda</translation> <translation id="1567993339577891801">JavaScript Console</translation> -<translation id="1568067597247500137">Redam tapak</translation> <translation id="1568323446248056064">Buka tetapan peranti paparan</translation> <translation id="1572266655485775982">Wi-Fi didayakan</translation> <translation id="1572585716423026576">Tetapkan sebagai kertas dinding</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">Tandatangan X9.62 ECDSA dengan SHA-1</translation> <translation id="1644574205037202324">Sejarah</translation> <translation id="1645516838734033527">Untuk memastikan <ph name="DEVICE_TYPE" /> anda selamat, Smart Lock memerlukan kunci skrin pada telefon anda.</translation> -<translation id="1646102270785326155">Semua fail dan data setempat yang berkaitan dengan pengguna ini akan dipadamkan secara kekal selepas pengguna ini dialih keluar. $1 masih boleh log masuk kemudian.</translation> <translation id="1646982517418478057">Sila masukkan kata laluan untuk menyulitkan sijil ini</translation> <translation id="164814987133974965">Pengguna diselia boleh meneroka web dengan bimbingan anda. Sebagai pengurus pengguna diselia, anda boleh <ph name="BEGIN_BOLD" />benarkan atau larang<ph name="END_BOLD" /> tapak web tertentu, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Sambungan turut mengawal halaman yang ditunjukkan apabila anda membuat carian dari Kotak Omni.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Untuk mengalih keluar apl, pergi ke Tetapan > Gedung Google Play > Urus pilihan Android > Apl atau Pengurus aplikasi. Kemudian, ketik apl yang ingin dinyahpasang (anda mungkin perlu meleret ke kanan atau ke kiri untuk mencari apl). Kemudian, ketik Nyahpasang atau Lumpuhkan.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Menghantar permintaan...</translation> -<translation id="1732215134274276513">Tab Buka Pin</translation> <translation id="1733383495376208985">Sulitkan data yang disegerakkan dengan <ph name="BEGIN_LINK" />ungkapan laluan penyegerakan<ph name="END_LINK" /> anda sendiri. Penyulitan ini tidak termasuk kaedah pembayaran dan alamat daripada Google Pay.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> mungkin tidak dapat mengemas kini dengan sendirinya</translation> <translation id="1736419249208073774">Teroka</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Semua fail</translation> <translation id="1809734401532861917">Tambahkan penanda halaman, sejarah, kata laluan dan tetapan saya yang lain pada <ph name="USER_EMAIL_ADDRESS" />.</translation> <translation id="1810764548349082891">Pratonton tidak tersedia</translation> -<translation id="1812631533912615985">Nyahpin tab</translation> <translation id="1813278315230285598">Perkhidmatan</translation> <translation id="18139523105317219">Nama Pihak EDI</translation> <translation id="1815083418640426271">Tampalkan Sebagai Teks Biasa</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chrome sedang dikawal oleh perisian ujian automatik.</translation> <translation id="2070909990982335904">Nama bermula dengan titik dikhaskan untuk sistem. Sila pilih nama lain.</translation> <translation id="2071393345806050157">Tiada fail log setempat.</translation> -<translation id="2074527029802029717">Buka pin tab</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% Bateri</translation> <translation id="2075959085554270910">Membolehkan anda mendayakan/melumpuhkan ketik-untuk-klik dan seretan ketik</translation> <translation id="2076269580855484719">Sembunyikan pemalam ini</translation> @@ -1358,7 +1349,6 @@ <translation id="3045447014237878114">Tapak ini memuat turun berbilang fail secara automatik</translation> <translation id="3046910703532196514">Haaman Web, Lengkap</translation> <translation id="304747341537320566">Enjin Pertuturan</translation> -<translation id="304826556400666995">Nyahredam Beberapa Tab</translation> <translation id="3053013834507634016">Penggunaan Penting Sijil</translation> <translation id="3057861065630527966">Sandarkan foto dan video anda</translation> <translation id="3060379269883947824">Dayakan pilih untuk bercakap</translation> @@ -2344,7 +2334,6 @@ <translation id="4628762811416793313">Penyediaan bekas Linux tidak lengkap. Sila cuba lagi.</translation> <translation id="4628948037717959914">Foto</translation> <translation id="4631887759990505102">Artis</translation> -<translation id="4632483769545853758">Nyahredam Tab</translation> <translation id="4633003931260532286">Sambungan memerlukan "<ph name="IMPORT_NAME" />" dengan versi minimum "<ph name="IMPORT_VERSION" />", tetapi hanya versi "<ph name="INSTALLED_VERSION" />" yang ada dipasang</translation> <translation id="4634771451598206121">Log masuk semula...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> tidak tersedia untuk pengguna Tetamu.</translation> @@ -2409,7 +2398,6 @@ <translation id="4736292055110123391">Segerakkan penanda halaman, kata laluan, sejarah dan pelbagai lagi item anda pada semua peranti anda</translation> <translation id="4737715515457435632">Sila sambung ke rangkaian</translation> <translation id="473775607612524610">Kemas kini</translation> -<translation id="474217410105706308">Redam Tab</translation> <translation id="4742746985488890273">Sematkan pada Rak</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Ketahui cara mengemas kini aplikasi<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Mesej</translation> @@ -2634,7 +2622,6 @@ <translation id="5094721898978802975">Berkomunikasi dengan aplikasi asli yang bekerjasama</translation> <translation id="5097002363526479830">Gagal untuk bersambung ke rangkaian '<ph name="NAME" />': <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Buka semua penanda halaman</translation> -<translation id="5105855035535475848">Pin tab</translation> <translation id="5108967062857032718">Tetapan - Alih keluar apl Android</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">&Pengurus Penanda Halaman</translation> @@ -2699,7 +2686,6 @@ <translation id="520621735928254154">Ralat Pengimportan Sijil</translation> <translation id="5209320130288484488">Tiada peranti ditemui</translation> <translation id="5209518306177824490">Cap jari SHA-1</translation> -<translation id="5210365745912300556">Tutup tab</translation> <translation id="5213481667492808996">Perkhidmatan data '<ph name="NAME" />' anda sedia untuk digunakan</translation> <translation id="5213891612754844763">Tunjukkan tetapan proksi</translation> <translation id="521582610500777512">Foto telah dibuang</translation> @@ -2751,7 +2737,6 @@ <translation id="5272654297705279635">Tetapan tersuai</translation> <translation id="5275352920323889391">Anjing</translation> <translation id="5275973617553375938">Fail yang diperoleh semula dari Google Drive</translation> -<translation id="527605719918376753">Redam tab</translation> <translation id="527605982717517565">Sentiasa benarkan JavaScript di <ph name="HOST" /></translation> <translation id="5280426389926346830">Buat Pintasan?</translation> <translation id="528208740344463258">Untuk memuat turun dan menggunakan apl Android, anda perlu memasang kemas kini yang diperlukan ini dahulu. Semasa <ph name="DEVICE_TYPE" /> anda sedang dikemas kini, anda tidak boleh menggunakannya. <ph name="DEVICE_TYPE" /> anda akan dimulakan semula selepas pemasangan selesai.</translation> @@ -2874,7 +2859,6 @@ <translation id="5449551289610225147">Kata laluan tidak sah</translation> <translation id="5449588825071916739">Tanda Halaman Semua Tab</translation> <translation id="5449716055534515760">Tutup Te&tingkap</translation> -<translation id="5453029940327926427">Tutup tab</translation> <translation id="5454166040603940656">dengan <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Tidak sah</translation> <translation id="5457459357461771897">Baca dan padam foto, muzik dan media lain daripada komputer anda</translation> @@ -3339,7 +3323,6 @@ <translation id="6122875415561139701">Pengendalian tulis tidak dibenarkan pada: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">Sambungan berikut bergantung kepada sambungan ini:</translation> <translation id="6125479973208104919">Malangnya, anda perlu menambahkan akaun pada <ph name="DEVICE_TYPE" /> ini sekali lagi.</translation> -<translation id="612596694132302162">Nyahredam tapak</translation> <translation id="6129691635767514872">Data yang dipilih telah dialih keluar daripada Chrome dan peranti yang disegerakkan. Akaun Google anda mungkin mempunyai sejarah penyemakan imbas dalam bentuk lain seperti carian dan aktiviti daripada perkhidmatan Google yang lain di <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Komen Sijil Netscape</translation> <translation id="6129953537138746214">Ruang</translation> @@ -3542,7 +3525,6 @@ <translation id="6436164536244065364">Lihat di Kedai Web</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - Audio sedang dimainkan</translation> <translation id="6442187272350399447">Hebat</translation> -<translation id="6442697326824312960">Buka Pin Tab</translation> <translation id="6444070574980481588">Tetapkan tarikh dan masa</translation> <translation id="6445450263907939268">Jika anda tidak mahu perubahan ini, anda boleh mengembalikan tetapan anda yang terdahulu.</translation> <translation id="6447842834002726250">Kuki</translation> @@ -3745,7 +3727,6 @@ <translation id="6770664076092644100">Sahkan melalui NFC</translation> <translation id="6771503742377376720">Adalah Pihak Berkuasa Pensijilan</translation> <translation id="6777817260680419853">Ubah hala disekat</translation> -<translation id="6778959797435875428">Nyahredam tapak</translation> <translation id="677965093459947883">Sangat kecil</translation> <translation id="6780439250949340171">uruskan tetapan lain</translation> <translation id="6781284683813954823">Pautan Coretan</translation> @@ -4062,7 +4043,6 @@ <translation id="7257666756905341374">Baca data yang anda salin dan tampal</translation> <translation id="7258697411818564379">PIN anda telah ditambahkan</translation> <translation id="7262004276116528033">Perkhidmatan log masuk ini dihoskan oleh <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Tutup Tab</translation> <translation id="7268659760406822741">Perkhidmatan yang tersedia</translation> <translation id="7270858098575133036">Tanya apabila tapak mahu menggunakan mesej eksklusif sistem untuk mengakses peranti MIDI</translation> <translation id="7272674038937250585">Tiada perihalan disediakan</translation> @@ -4252,7 +4232,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">Kumpul semak</translation> <translation id="7576976045740938453">Masalah berkaitan akaun mod tunjuk cara telah berlaku.</translation> -<translation id="7579149537961810247">Redam Tapak</translation> <translation id="7580671184200851182">Mainkan audio yang sama melalui semua pembesar suara (audio mono)</translation> <translation id="7581462281756524039">Pembersih</translation> <translation id="7582582252461552277">Lebih suka rangkaian ini</translation> @@ -4606,7 +4585,6 @@ <translation id="8068253693380742035">Sentuh untuk mengelog masuk</translation> <translation id="8069615408251337349">Cetakan Awan Google</translation> <translation id="8071432093239591881">Cetak sebagai imej</translation> -<translation id="8072988827236813198">Pin Tab</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Data apl boleh jadi sebarang data yang telah disimpan oleh apl (berdasarkan tetapan pembangun), termasuk data seperti kenalan, mesej dan foto.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Data sandaran tidak akan ditolak daripada kuota storan Drive anak anda.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Anda boleh mematikan perkhidmatan ini dalam Tetapan.<ph name="END_PARAGRAPH3" /></translation> @@ -4793,7 +4771,6 @@ <translation id="8368859634510605990">&Buka semua penanda halaman</translation> <translation id="8371695176452482769">Cakap sekarang</translation> <translation id="8372369524088641025">Kekunci WEP teruk</translation> -<translation id="8373553483208508744">Redam beberapa tab</translation> <translation id="8378714024927312812">Diurus oleh organisasi anda</translation> <translation id="8379878387931047019">Peranti ini tidak menyokong jenis kunci keselamatan yang diminta oleh tapak web ini</translation> <translation id="8382913212082956454">Salin &alamat e-mel</translation> @@ -4901,7 +4878,6 @@ <translation id="8546930481464505581">Sesuaikan Touch Bar</translation> <translation id="8547013269961688403">Dayakan penggadang skrin penuh</translation> <translation id="85486688517848470">Tahan kekunci Cari untuk menukar gelagat kekunci di baris atas</translation> -<translation id="855081842937141170">Pin tab</translation> <translation id="8551388862522347954">Lesen</translation> <translation id="8553342806078037065">Urus orang lain</translation> <translation id="8554899698005018844">Tiada bahasa</translation> @@ -5216,7 +5192,6 @@ <translation id="9038430547971207796">Selepas ini, telefon anda akan membuka kunci <ph name="DEVICE_TYPE" />. Matikan Smart Lock dalam Tetapan.</translation> <translation id="9038649477754266430">Gunakan perkhidmatan ramalan untuk memuatkan halaman lebih cepat</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Redam Beberapa Tab</translation> <translation id="9040661932550800571">Kemas kini kata laluan untuk <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Akses kepada fail setempat pada mesin anda dilumpuhkan oleh pentadbir anda</translation> <translation id="9042893549633094279">Privasi dan keselamatan</translation> @@ -5314,7 +5289,6 @@ <translation id="920045321358709304">Cari <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Pilihan kunci skrin</translation> <translation id="9203398526606335860">&Dayakan pemprofilan</translation> -<translation id="9203478404496196495">Nyahredam Tab</translation> <translation id="9203904171912129171">Pilih peranti</translation> <translation id="9203962528777363226">Pentadbir peranti ini telah melumpuhkan pengguna baharu daripada ditambah</translation> <translation id="9213073329713032541">Pemasangan berjaya dimulakan.</translation>
diff --git a/chrome/app/resources/generated_resources_nl.xtb b/chrome/app/resources/generated_resources_nl.xtb index 7ae0019..75908ecc 100644 --- a/chrome/app/resources/generated_resources_nl.xtb +++ b/chrome/app/resources/generated_resources_nl.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Druk op ESCAPE om over te slaan (alleen voor niet-officiële builds).</translation> <translation id="1093457606523402488">Zichtbare netwerken:</translation> <translation id="1094607894174825014">Lees- of schrijfbewerking is aangevraagd met een ongeldige verschuiving op: <ph name="DEVICE_NAME" />.</translation> -<translation id="109758035718544977">Geluid van sites dempen opheffen</translation> <translation id="1097658378307015415">Voordat je inlogt, log je eerst in als gast om het netwerk <ph name="NETWORK_ID" /> te activeren.</translation> <translation id="1103523840287552314"><ph name="LANGUAGE" /> altijd vertalen</translation> <translation id="1108600514891325577">&Stop</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Gebruik een incognitovenster om te internetten zonder dat je browsegeschiedenis wordt opgeslagen</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> vingerafdrukken ingesteld</translation> <translation id="1215411991991485844">Nieuwe achtergrondapp toegevoegd</translation> -<translation id="1216654534877302979">Geluid van sites dempen</translation> <translation id="1216659994753476700">We kunnen geen toegang krijgen tot je profiel. De bestanden en gegevens op dit apparaat zijn mogelijk verloren gegaan.<ph name="BR" /> <ph name="BR" /> Je moet je profiel weer instellen.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Gegevens opslaan in je Google Drive-account</translation> <translation id="1288037062697528143">Nachtverlichting wordt automatisch ingeschakeld bij zonsondergang</translation> <translation id="1288300545283011870">Spraakeigenschappen</translation> -<translation id="1293177648337752319">Geluid van site dempen opheffen</translation> <translation id="1293264513303784526">USB-C-apparaat (poort aan linkerkant)</translation> <translation id="1293556467332435079">Bestanden</translation> <translation id="1296497012903089238">Type certificaat</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Homepage is de nieuwe tabbladpagina</translation> <translation id="1436671784520050284">Doorgaan met instellen</translation> <translation id="1436784010935106834">Verwijderd</translation> -<translation id="1438632560381091872">Dempen tabbladen opheffen</translation> <translation id="1442392616396121389">Routeringsvoorvoegsel</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> geselecteerd</translation> <translation id="1444628761356461360">Deze instelling wordt beheerd door de eigenaar van het apparaat, <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Er is een ander toetsenbord aangesloten sinds de laatste keer dat je je wachtwoord hebt ingevoerd. Mogelijk wordt geprobeerd om je toetsaanslagen te stelen.</translation> <translation id="1567750922576943685">Wanneer je je identiteit verifieert, blijven je persoonlijke gegevens beter beschermd</translation> <translation id="1567993339577891801">JavaScript-console</translation> -<translation id="1568067597247500137">Geluid van site dempen</translation> <translation id="1568323446248056064">Weergave-instellingen van apparaat openen</translation> <translation id="1572266655485775982">Wifi inschakelen</translation> <translation id="1572585716423026576">Instellen als achtergrond</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">X9.62 ECDSA-handtekening met SHA-1</translation> <translation id="1644574205037202324">Geschiedenis</translation> <translation id="1645516838734033527">Smart Lock vereist een schermvergrendeling op je telefoon om je <ph name="DEVICE_TYPE" /> te beveiligen.</translation> -<translation id="1646102270785326155">Alle bestanden en lokale gegevens die zijn gekoppeld aan deze gebruiker, worden definitief verwijderd zodra deze gebruiker is verwijderd. $1 kan later nog steeds inloggen.</translation> <translation id="1646982517418478057">Geef een wachtwoord op om dit certificaat te versleutelen</translation> <translation id="164814987133974965">Een gebruiker met beperkte rechten kan onder je toezicht op internet browsen. Als de beheerder van een gebruiker met beperkte rechten kun je bepaalde websites <ph name="BEGIN_BOLD" />toestaan of weigeren<ph name="END_BOLD" />, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Hiermee wordt ook gecontroleerd welke pagina wordt weergegeven wanneer je vanuit de omnibox zoekt.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Als je apps wilt verwijderen, ga je naar Instellingen > Google Play Store > Android-voorkeuren beheren > Apps of App-beheer en tik je op de app die je wilt verwijderen (je moet mogelijk naar rechts of links vegen om de app te vinden). Tik vervolgens op Verwijderen of Uitschakelen.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Aanvraag wordt verstuurd...</translation> -<translation id="1732215134274276513">Tabbladen losmaken</translation> <translation id="1733383495376208985">Gesynchroniseerde gegevens versleutelen met je eigen <ph name="BEGIN_LINK" />wachtwoordzin voor synchronisatie<ph name="END_LINK" />. Hieronder vallen geen betaalmethoden en adressen van Google Pay.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> kan zichzelf mogelijk niet updaten</translation> <translation id="1736419249208073774">Verkennen</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Alle bestanden</translation> <translation id="1809734401532861917">Mijn bladwijzers, geschiedenis, wachtwoorden en andere instellingen toevoegen aan <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Geen voorbeeld beschikbaar</translation> -<translation id="1812631533912615985">Tabbladen losmaken</translation> <translation id="1813278315230285598">Services</translation> <translation id="18139523105317219">EDI Partynaam</translation> <translation id="1815083418640426271">Plakken als tekst zonder opmaak</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chrome wordt beheerd door geautomatiseerde testsoftware.</translation> <translation id="2070909990982335904">Namen die beginnen met een stip, zijn gereserveerd voor het systeem. Kies een andere naam.</translation> <translation id="2071393345806050157">Geen lokaal logbestand.</translation> -<translation id="2074527029802029717">Tabblad losmaken</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% batterijlading</translation> <translation id="2075959085554270910">Hiermee kun je tikken-om-te-klikken en tikken-en-slepen in- en uitschakelen</translation> <translation id="2076269580855484719">Deze plugin verbergen</translation> @@ -1352,7 +1343,6 @@ <translation id="3045447014237878114">Deze site heeft automatisch meerdere bestanden gedownload</translation> <translation id="3046910703532196514">Webpagina, compleet</translation> <translation id="304747341537320566">Spraakengines</translation> -<translation id="304826556400666995">Dempen tabbladen opheffen</translation> <translation id="3053013834507634016">Sleutelgebruik voor certificaat</translation> <translation id="3057861065630527966">Een back-up van je foto's en video's maken</translation> <translation id="3060379269883947824">'Selecteer om uitgesproken te worden' inschakelen</translation> @@ -2335,7 +2325,6 @@ <translation id="4628762811416793313">De installatie van de Linux-container is niet voltooid. Probeer het opnieuw.</translation> <translation id="4628948037717959914">Foto</translation> <translation id="4631887759990505102">Artiest</translation> -<translation id="4632483769545853758">Dempen tabblad opheffen</translation> <translation id="4633003931260532286">Voor deze extensie is minimaal versie '<ph name="IMPORT_VERSION" />' van '<ph name="IMPORT_NAME" />' vereist, maar alleen versie '<ph name="INSTALLED_VERSION" />' is geïnstalleerd</translation> <translation id="4634771451598206121">Opnieuw inloggen...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> is niet beschikbaar voor gastgebruikers.</translation> @@ -2399,7 +2388,6 @@ <translation id="4735803855089279419">Het systeem kan de apparaat-ID's voor dit apparaat niet bepalen.</translation> <translation id="4737715515457435632">Maak verbinding met een netwerk</translation> <translation id="473775607612524610">Updaten</translation> -<translation id="474217410105706308">Tabblad dempen</translation> <translation id="4742746985488890273">Vastmaken aan plank</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Meer informatie over hoe je apps updatet<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Berichten</translation> @@ -2624,7 +2612,6 @@ <translation id="5094721898978802975">Communiceren met samenwerkende legitieme apps</translation> <translation id="5097002363526479830">Kan geen verbinding maken met het netwerk '<ph name="NAME" />': <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Alle bladwijzers openen</translation> -<translation id="5105855035535475848">Tabbladen vastzetten</translation> <translation id="5108967062857032718">Instellingen - Android-apps verwijderen</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">&Bladwijzermanager</translation> @@ -2690,7 +2677,6 @@ <translation id="520621735928254154">Fout bij importeren van certificaat</translation> <translation id="5209320130288484488">Geen apparaten gevonden</translation> <translation id="5209518306177824490">SHA-1-vingerafdruk</translation> -<translation id="5210365745912300556">Tabblad sluiten</translation> <translation id="5213481667492808996">Je dataservice '<ph name="NAME" />' is klaar voor gebruik</translation> <translation id="5213891612754844763">Proxyinstellingen weergeven</translation> <translation id="521582610500777512">Foto is geannuleerd</translation> @@ -2741,7 +2727,6 @@ <translation id="5270167208902136840">Nog <ph name="NUMBER_OF_MORE_APPS" /> apps weergeven</translation> <translation id="5275352920323889391">Hond</translation> <translation id="5275973617553375938">Bestanden hersteld vanaf Google Drive</translation> -<translation id="527605719918376753">Tabblad dempen</translation> <translation id="527605982717517565">JavaScript altijd toestaan op <ph name="HOST" /></translation> <translation id="5280426389926346830">Snelkoppeling maken?</translation> <translation id="528208740344463258">Als je Android-apps wilt downloaden en gebruiken, moet je eerst deze vereiste update installeren. Je kunt je <ph name="DEVICE_TYPE" /> tijdens het updaten niet gebruiken. Je <ph name="DEVICE_TYPE" /> wordt opnieuw opgestart nadat de installatie is voltooid.</translation> @@ -2864,7 +2849,6 @@ <translation id="5449551289610225147">Ongeldig wachtwoord</translation> <translation id="5449588825071916739">Bladwijzer toevoegen aan alle tabbladen</translation> <translation id="5449716055534515760">Ve&nster sluiten</translation> -<translation id="5453029940327926427">Tabbladen sluiten</translation> <translation id="5454166040603940656">met <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Ongeldig</translation> <translation id="5457459357461771897">Foto's, muziek en andere media van je computer lezen en verwijderen</translation> @@ -3329,7 +3313,6 @@ <translation id="6122875415561139701">Schrijfbewerking is niet toegestaan op: <ph name="DEVICE_NAME" />.</translation> <translation id="6124650939968185064">De volgende extensies zijn afhankelijk van deze extensie:</translation> <translation id="6125479973208104919">Je moet je account opnieuw toevoegen aan deze <ph name="DEVICE_TYPE" />.</translation> -<translation id="612596694132302162">Geluid van site dempen opheffen</translation> <translation id="6129691635767514872">De geselecteerde gegevens zijn verwijderd uit Chrome en van gesynchroniseerde apparaten. Voor je Google-account kunnen andere vormen van browsegeschiedenis (zoals zoekopdrachten en activiteit uit andere Google-services) beschikbaar zijn via <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Opmerking van Netscape-certificaat</translation> <translation id="6129953537138746214">Spatie</translation> @@ -3532,7 +3515,6 @@ <translation id="6436164536244065364">Bekijken in Web Store</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" />: audio wordt afgespeeld</translation> <translation id="6442187272350399447">Supercool</translation> -<translation id="6442697326824312960">Tabblad losmaken</translation> <translation id="6444070574980481588">Datum en tijd instellen</translation> <translation id="6445450263907939268">Als je deze wijzigingen niet wilt aanbrengen, kun je je vorige instellingen herstellen.</translation> <translation id="6447842834002726250">Cookies</translation> @@ -3735,7 +3717,6 @@ <translation id="6770664076092644100">Verifiëren via NFC</translation> <translation id="6771503742377376720">Is een certificeringsinstantie</translation> <translation id="6777817260680419853">Omleiding geblokkeerd</translation> -<translation id="6778959797435875428">Geluid van sites dempen opheffen</translation> <translation id="677965093459947883">Zeer klein</translation> <translation id="6780439250949340171">andere instellingen beheren</translation> <translation id="6781284683813954823">Link naar doodle</translation> @@ -4052,7 +4033,6 @@ <translation id="7257666756905341374">Gegevens lezen die je kopieert en plakt</translation> <translation id="7258697411818564379">Je pincode is toegevoegd</translation> <translation id="7262004276116528033">Deze inlogservice wordt gehost door <ph name="SAML_DOMAIN" />.</translation> -<translation id="7268365133021434339">Tabbladen sluiten</translation> <translation id="7268659760406822741">Beschikbare services</translation> <translation id="7270858098575133036">Vragen als een site berichten exclusief voor het systeem wil gebruiken om toegang te krijgen tot MIDI-apparaten</translation> <translation id="7272674038937250585">Geen beschrijving opgegeven</translation> @@ -4242,7 +4222,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">Sorteren</translation> <translation id="7576976045740938453">Er is een probleem opgetreden met het demomodus-account.</translation> -<translation id="7579149537961810247">Geluid van sites dempen</translation> <translation id="7580671184200851182">Dezelfde audio afspelen via alle speakers (mono-audio)</translation> <translation id="7581462281756524039">Een cleanup-tool</translation> <translation id="7582582252461552277">Dit netwerk voorrang geven</translation> @@ -4595,7 +4574,6 @@ <translation id="8068253693380742035">Tik om in te loggen</translation> <translation id="8069615408251337349">Google Cloudprinter</translation> <translation id="8071432093239591881">Afdrukken als afbeelding</translation> -<translation id="8072988827236813198">Tabbladen vastzetten</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />App-gegevens kunnen alle gegevens omvatten die een app heeft opgeslagen (op basis van de instellingen van de ontwikkelaar), waaronder gegevens zoals contacten, berichten en foto's.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Back-upgegevens tellen niet mee voor het Drive-opslagquotum van je kind.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Je kunt deze service uitschakelen via Instellingen.<ph name="END_PARAGRAPH3" /></translation> @@ -4781,7 +4759,6 @@ <translation id="8368859634510605990">Alle bladwijzers &openen</translation> <translation id="8371695176452482769">Begin nu te spreken</translation> <translation id="8372369524088641025">Slechte WEP-sleutel</translation> -<translation id="8373553483208508744">Tabbladen dempen</translation> <translation id="8378714024927312812">Beheerd door je organisatie</translation> <translation id="8379878387931047019">Dit apparaat biedt geen ondersteuning voor het type beveiligingssleutel dat is vereist voor deze website</translation> <translation id="8382913212082956454">&E-mailadres kopiëren</translation> @@ -4889,7 +4866,6 @@ <translation id="8546930481464505581">Aanraakbalk aanpassen</translation> <translation id="8547013269961688403">'Volledig scherm vergroten' inschakelen</translation> <translation id="85486688517848470">Houd de zoektoets ingedrukt om het gedrag van de toetsen in de bovenste rij om te schakelen</translation> -<translation id="855081842937141170">Tabblad vastzetten</translation> <translation id="8551388862522347954">Licenties</translation> <translation id="8553342806078037065">Andere mensen beheren</translation> <translation id="8554899698005018844">Geen taal</translation> @@ -5204,7 +5180,6 @@ <translation id="9038430547971207796">De volgende keer wordt je <ph name="DEVICE_TYPE" /> ontgrendeld met je telefoon. Schakel Smart Lock uit in Instellingen.</translation> <translation id="9038649477754266430">Een voorspellingsservice gebruiken om pagina's sneller te laden</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Tabbladen dempen</translation> <translation id="9040661932550800571">Wachtwoord updaten voor <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Toegang tot lokale bestanden op je computer is door je beheerder uitgeschakeld</translation> <translation id="9042893549633094279">Privacy en beveiliging</translation> @@ -5302,7 +5277,6 @@ <translation id="920045321358709304">Zoeken op <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Schermvergrendelingsopties</translation> <translation id="9203398526606335860">&Profiling ingeschakeld</translation> -<translation id="9203478404496196495">Dempen tabblad opheffen</translation> <translation id="9203904171912129171">Een apparaat selecteren</translation> <translation id="9203962528777363226">De beheerder van dit apparaat heeft het toevoegen van nieuwe gebruikers uitgeschakeld</translation> <translation id="9213073329713032541">De installatie is gestart.</translation>
diff --git a/chrome/app/resources/generated_resources_no.xtb b/chrome/app/resources/generated_resources_no.xtb index b52661f..b428c7c 100644 --- a/chrome/app/resources/generated_resources_no.xtb +++ b/chrome/app/resources/generated_resources_no.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Trykk på ESC for å hoppe over denne (bare uoffisielle delversjoner).</translation> <translation id="1093457606523402488">Synlige nettverk:</translation> <translation id="1094607894174825014">Det ble bedt om en lese- eller skriveoperasjon med en ugyldig forskyvning på: «<ph name="DEVICE_NAME" />».</translation> -<translation id="109758035718544977">Slå på lyden for nettsteder</translation> <translation id="1097658378307015415">Gå inn som gjest for å aktivere nettverket <ph name="NETWORK_ID" /> før du logger deg på.</translation> <translation id="1103523840287552314">Oversett alltid <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Stopp</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Med et inkognitovindu kan du bruke nettet uten at nettlesingsloggen lagres</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> fingeravtrykk er registrert</translation> <translation id="1215411991991485844">Nytt bakgrunnsprogram er lagt til</translation> -<translation id="1216654534877302979">Kutt lyden for nettsteder</translation> <translation id="1216659994753476700">Beklager, men vi får ikke tilgang til profilen din. Det kan hende filer og data som er lagret på denne enheten, er blitt borte.<ph name="BR" /> <ph name="BR" /> Du må konfigurere profilen din på nytt.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">lagre data i Google Disk-kontoen din</translation> <translation id="1288037062697528143">Nattlys blir slått på automatisk ved solnedgang</translation> <translation id="1288300545283011870">Taleegenskaper</translation> -<translation id="1293177648337752319">Slå på lyden for nettsted</translation> <translation id="1293264513303784526">USB-C-enhet (porten på venstre side)</translation> <translation id="1293556467332435079">Filer</translation> <translation id="1296497012903089238">Sertifikattype</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Startsiden er Ny fane-siden</translation> <translation id="1436671784520050284">Fortsett konfigureringen</translation> <translation id="1436784010935106834">Fjernet</translation> -<translation id="1438632560381091872">Slå på lyden for fanene</translation> <translation id="1442392616396121389">Rutingprefiks</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> valgt</translation> <translation id="1444628761356461360">Denne innstillingen administreres av enhetseieren, <ph name="OWNER_EMAIL" /> .</translation> @@ -385,7 +381,6 @@ <translation id="1567387640189251553">Et annet tastatur er koblet til etter at du sist skrev inn passordet ditt. Det brukes kanskje til å stjele tastetrykkene dine.</translation> <translation id="1567750922576943685">Ved å bekrefte identiteten din bidrar du til å beskytte personopplysningene dine</translation> <translation id="1567993339577891801">JavaScript-konsoll</translation> -<translation id="1568067597247500137">Kutt lyden for nettsted</translation> <translation id="1568323446248056064">Åpne skjerminnstillingene på enheten</translation> <translation id="1572266655485775982">Slå på Wi-Fi</translation> <translation id="1572585716423026576">Angi som bakgrunn</translation> @@ -437,7 +432,6 @@ <translation id="1643072738649235303">X9.62 ECDSA-signatur med SHA-1</translation> <translation id="1644574205037202324">Logg</translation> <translation id="1645516838734033527">Smart Lock krever en skjermlås på telefonen for å holde <ph name="DEVICE_TYPE" />-enheten trygg.</translation> -<translation id="1646102270785326155">Alle filer og lokale data som er tilknyttet denne brukeren, slettes permanent når brukeren fjernes. $1 kan fortsatt logge på senere.</translation> <translation id="1646982517418478057">Skriv inn et passord for å kryptere dette sertifikatet.</translation> <translation id="164814987133974965">En administrert bruker kan utforske nettet med din veiledning. Som administrator for en administrert bruker, kan du <ph name="BEGIN_BOLD" />tillate eller blokkere<ph name="END_BOLD" /> bestemte nettsteder, @@ -496,7 +490,6 @@ <translation id="1729533290416704613">Den styrer også hvilken side som vises når du søker fra multifunksjonsfeltet.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />For å fjerne apper, gå til Innstillinger > Google Play Butikk > Administrer Android-innstillinger > Apper eller Appstyring. Trykk på appen du vil avinstallere (du må kanskje sveipe til høyre eller venstre for å finne den). Trykk deretter på Avinstaller eller Slå av.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Sender forespørsel...</translation> -<translation id="1732215134274276513">Løsne faner</translation> <translation id="1733383495376208985">Kryptér synkroniserte data med din egen <ph name="BEGIN_LINK" />passordfrase for synkronisering<ph name="END_LINK" />. Dette inkluderer ikke betalingsmåter og adresser fra Google Pay.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> oppdateres muligens ikke automatisk</translation> <translation id="1736419249208073774">Utforsk</translation> @@ -548,7 +541,6 @@ <translation id="1807938677607439181">Alle filer</translation> <translation id="1809734401532861917">Legg til bokmerker, loggen, passord og andre innstillinger i <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Ingen forhåndsvisning er tilgjengelig</translation> -<translation id="1812631533912615985">Løsne faner</translation> <translation id="1813278315230285598">Tjenester</translation> <translation id="18139523105317219">Navn på EDI-enhet</translation> <translation id="1815083418640426271">Lim inn som ren tekst</translation> @@ -707,7 +699,6 @@ <translation id="2065405795449409761">Chrome kontrolleres av programvare for automatisk testing.</translation> <translation id="2070909990982335904">Navn som starter med et punktum, er reservert for systemet. Velg et annet navn.</translation> <translation id="2071393345806050157">Ingen lokal loggfil.</translation> -<translation id="2074527029802029717">Løsne fanen</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" /> % batteri</translation> <translation id="2075959085554270910">Lar deg slå på og av berøringsklikk og trykk-og-dra</translation> <translation id="2076269580855484719">Skjul dette programtillegget</translation> @@ -794,7 +785,7 @@ <translation id="2199298570273670671">Feil</translation> <translation id="2200094388063410062">E-post</translation> <translation id="2200356397587687044">Chrome trenger tillatelse for å fortsette</translation> -<translation id="2200603218210188859">USB-enhetsinnstillinger</translation> +<translation id="2200603218210188859">Innstillinger for USB-enheter</translation> <translation id="220138918934036434">Skjul knappen</translation> <translation id="2202898655984161076">Det oppstod et problem med oppføring av skrivere. Enkelte av skriverne dine er ikke registrert på <ph name="CLOUD_PRINT_NAME" />.</translation> <translation id="2203682048752833055">Søkemotoren som brukes i <ph name="BEGIN_LINK" />adressefeltet<ph name="END_LINK" /></translation> @@ -1348,7 +1339,6 @@ <translation id="3045447014237878114">Dette nettstedet har lastet ned flere filer automatisk</translation> <translation id="3046910703532196514">Nettside, fullstendig</translation> <translation id="304747341537320566">Talemotorer</translation> -<translation id="304826556400666995">Slå på lyden for fanene</translation> <translation id="3053013834507634016">Bruk av sertifikatnøkkel</translation> <translation id="3057861065630527966">Sikkerhetskopiér bildene og videoene dine</translation> <translation id="3060379269883947824">Slå på Tekstopplesing</translation> @@ -2328,7 +2318,6 @@ <translation id="4628762811416793313">Konfigureringen av Linux-beholderen ble ikke fullført. Prøv på nytt.</translation> <translation id="4628948037717959914">Bilde</translation> <translation id="4631887759990505102">Artist</translation> -<translation id="4632483769545853758">Slå på lyden for fanen</translation> <translation id="4633003931260532286">Utvidelsen krever «<ph name="IMPORT_NAME" />» med «<ph name="IMPORT_VERSION" />» som minimumsversjon, men bare versjon «<ph name="INSTALLED_VERSION" />» er installert</translation> <translation id="4634771451598206121">Logg på igjen</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> er ikke tilgjengelig for gjestebrukere.</translation> @@ -2392,7 +2381,6 @@ <translation id="4735803855089279419">Systemet kunne ikke fastslå enhetsidentifikatorer for denne enheten.</translation> <translation id="4737715515457435632">Du må koble til et nettverk</translation> <translation id="473775607612524610">Oppdater</translation> -<translation id="474217410105706308">Slå av lyden for fanen</translation> <translation id="4742746985488890273">Fest til hyllen</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Finn ut hvordan du oppdaterer programmer<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Meldinger</translation> @@ -2617,7 +2605,6 @@ <translation id="5094721898978802975">kommunisere med samarbeidende integrerte apper</translation> <translation id="5097002363526479830">Kunne ikke koble til nettverket «<ph name="NAME" />»: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Åpne alle bokmerker</translation> -<translation id="5105855035535475848">Fest faner</translation> <translation id="5108967062857032718">Innstillinger – Fjern Android-apper</translation> <translation id="5109044022078737958">Sporty</translation> <translation id="5111692334209731439">&Bokmerkebehandling</translation> @@ -2674,7 +2661,7 @@ <translation id="5185386675596372454">Den nyeste versjonen av <ph name="EXTENSION_NAME" /> er deaktivert fordi den krever ytterligere tillatelser.</translation> <translation id="5187295959347858724">Du er nå pålogget <ph name="SHORT_PRODUCT_NAME" />. Bokmerkene, loggen og de andre innstillingene dine blir synkronisert med Google-kontoen din.</translation> <translation id="5187826826541650604"><ph name="KEY_NAME" /> (<ph name="DEVICE" />)</translation> -<translation id="5187892128515678283">Del en USB-enhet med Linux ved å sette bryteren til på. Delingen varer bare frem til enheten kobles fra.</translation> +<translation id="5187892128515678283">Del en USB-enhet med Linux ved å slå bryteren på. Delingen varer bare frem til enheten kobles fra.</translation> <translation id="51918995459521422"><ph name="ORIGIN" /> ber om å laste ned flere filer</translation> <translation id="5204673965307125349">Utfør Powerwash på enheten, og prøv på nytt.</translation> <translation id="5204967432542742771">Skriv inn passordet</translation> @@ -2682,7 +2669,6 @@ <translation id="520621735928254154">Feil ved sertifikatimport</translation> <translation id="5209320130288484488">Finner ingen enheter</translation> <translation id="5209518306177824490">SHA-1-fingeravtrykk</translation> -<translation id="5210365745912300556">Lukk fanen</translation> <translation id="5213481667492808996">Datatjenesten «<ph name="NAME" />» er klar for bruk</translation> <translation id="5213891612754844763">Vis innstillingene for proxy-tjener</translation> <translation id="521582610500777512">Bildet er forkastet</translation> @@ -2733,7 +2719,6 @@ <translation id="5270167208902136840">Vis <ph name="NUMBER_OF_MORE_APPS" /> apper til</translation> <translation id="5275352920323889391">Hund</translation> <translation id="5275973617553375938">Gjenopprettede filer fra Google Disk</translation> -<translation id="527605719918376753">Slå av lyden for fanen</translation> <translation id="527605982717517565">Tillat alltid JavaScript på <ph name="HOST" /></translation> <translation id="5280426389926346830">Vil du opprette en snarvei?</translation> <translation id="528208740344463258">Du må installere en oppdatering før du kan laste ned og bruke Android-apper. Du kan ikke bruke <ph name="DEVICE_TYPE" /> mens den oppdateres. <ph name="DEVICE_TYPE" /> starter på nytt når installasjonen er ferdig.</translation> @@ -2856,7 +2841,6 @@ <translation id="5449551289610225147">Ugyldig passord</translation> <translation id="5449588825071916739">Angi bokmerker for alle faner</translation> <translation id="5449716055534515760">Lukk vin&du</translation> -<translation id="5453029940327926427">Lukk faner</translation> <translation id="5454166040603940656">med <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Ugyldig</translation> <translation id="5457459357461771897">lese og slette bilder, musikk og andre medier fra datamaskinen din</translation> @@ -3321,7 +3305,6 @@ <translation id="6122875415561139701">Skriveoperasjonen er ikke tillatt på: «<ph name="DEVICE_NAME" />».</translation> <translation id="6124650939968185064">Disse utvidelsene er avhengige av denne utvidelsen:</translation> <translation id="6125479973208104919">Du må dessverre legge til kontoen din på denne <ph name="DEVICE_TYPE" />-enheten på nytt.</translation> -<translation id="612596694132302162">Slå på lyden for nettsted</translation> <translation id="6129691635767514872">De valgte dataene er fjernet fra Chrome og alle synkroniserte enheter. Det kan hende Google-kontoen din har andre typer nettlesingslogger, for eksempel for søk og aktivitet fra andre Google-tjenester, på <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Kommentar til Netscape-sertifikat</translation> <translation id="6129953537138746214">Mellomrom</translation> @@ -3524,7 +3507,6 @@ <translation id="6436164536244065364">Se i Nettmarked</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – lyd spilles av</translation> <translation id="6442187272350399447">Mega</translation> -<translation id="6442697326824312960">Løsne fanen</translation> <translation id="6444070574980481588">Angi dato og klokkeslett</translation> <translation id="6445450263907939268">Hvis du ikke ønsker disse endringene, kan du gjenopprette de tidligere innstillingene dine.</translation> <translation id="6447842834002726250">Informasjonskapsler</translation> @@ -3727,7 +3709,6 @@ <translation id="6770664076092644100">Bekreft via NFC</translation> <translation id="6771503742377376720">Er en sertifiseringsinstans</translation> <translation id="6777817260680419853">Viderekobling er blokkert</translation> -<translation id="6778959797435875428">Slå på lyden for nettsteder</translation> <translation id="677965093459947883">Veldig liten</translation> <translation id="6780439250949340171">administrer andre innstillinger</translation> <translation id="6781284683813954823">Doodle-link</translation> @@ -4044,7 +4025,6 @@ <translation id="7257666756905341374">lese data du kopierer og limer inn</translation> <translation id="7258697411818564379">PIN-koden din er lagt til</translation> <translation id="7262004276116528033">Verten for denne påloggingstjenesten er <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Lukk faner</translation> <translation id="7268659760406822741">Tilgjengelige tjenester</translation> <translation id="7270858098575133036">Spør når nettsteder vil bruke systemeksklusive meldinger for å få tilgang til MIDI-enheter</translation> <translation id="7272674038937250585">Ingen beskrivelse er oppgitt</translation> @@ -4232,7 +4212,6 @@ <translation id="7576032389798113292">6 x 4</translation> <translation id="7576690715254076113">I rekkefølge</translation> <translation id="7576976045740938453">Det oppsto et problem med kontoen for demomodus.</translation> -<translation id="7579149537961810247">Kutt lyden for nettsteder</translation> <translation id="7580671184200851182">Spill den samme lyden på alle høyttalere (monolyd)</translation> <translation id="7581462281756524039">Et opprydningsverktøy</translation> <translation id="7582582252461552277">Foretrekk dette nettverket</translation> @@ -4586,7 +4565,6 @@ <translation id="8068253693380742035">Trykk for å logge på</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Skriv ut som bilde</translation> -<translation id="8072988827236813198">Fest faner</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Appdata kan være alle slags data apper har lagret (basert på utviklerinnstillingene), blant annet kontakter, meldinger og bilder.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />De sikkerhetskopierte dataene telles ikke med i Disk-lagringskvoten din.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Du kan slå av denne tjenesten i Innstillinger.<ph name="END_PARAGRAPH3" /></translation> @@ -4772,7 +4750,6 @@ <translation id="8368859634510605990">&Åpne alle bokmerker</translation> <translation id="8371695176452482769">Snakk nå</translation> <translation id="8372369524088641025">Feil WEP-nøkkel</translation> -<translation id="8373553483208508744">Slå av lyden for fanene</translation> <translation id="8378714024927312812">Administreres av organisasjonen din</translation> <translation id="8379878387931047019">Denne enheten støtter ikke den typen sikkerhetsnøkkel som kreves av dette nettstedet</translation> <translation id="8382913212082956454">Kopier &e-postadresse</translation> @@ -4880,7 +4857,6 @@ <translation id="8546930481464505581">Tilpass Touch Bar</translation> <translation id="8547013269961688403">Aktivér lupen for hele skjermen</translation> <translation id="85486688517848470">Hold Søk-tasten inne for å endre funksjonene for tastene på øverste rad</translation> -<translation id="855081842937141170">Fest fanen</translation> <translation id="8551388862522347954">Lisenser</translation> <translation id="8553342806078037065">Administrer andre</translation> <translation id="8554899698005018844">Ingen språk</translation> @@ -5194,7 +5170,6 @@ <translation id="9038430547971207796">Neste gang låser telefonen opp denne <ph name="DEVICE_TYPE" />-enheten. Du kan slå av Smart Lock i innstillingene.</translation> <translation id="9038649477754266430">Bruk en prediksjonstjeneste for å laste inn sider raskere</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Slå av lyden for fanene</translation> <translation id="9040661932550800571">Vil du oppdatere passordet for <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Administratoren din har deaktivert tilgang til lokale filer på maskinen din</translation> <translation id="9042893549633094279">Personvern og sikkerhet</translation> @@ -5292,7 +5267,6 @@ <translation id="920045321358709304">Søk med <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Alternativer for skjermlås</translation> <translation id="9203398526606335860">&Profilering aktivert</translation> -<translation id="9203478404496196495">Slå på lyden for fanen</translation> <translation id="9203904171912129171">Velg enhet</translation> <translation id="9203962528777363226">Administratoren til denne enheten har deaktivert tillegging av nye brukere</translation> <translation id="9213073329713032541">Installeringen er startet.</translation>
diff --git a/chrome/app/resources/generated_resources_pl.xtb b/chrome/app/resources/generated_resources_pl.xtb index 66c5eb57..7176baed 100644 --- a/chrome/app/resources/generated_resources_pl.xtb +++ b/chrome/app/resources/generated_resources_pl.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Naciśnij ESCAPE, aby pominąć aktualizację (tylko nieoficjalne kompilacje).</translation> <translation id="1093457606523402488">Widoczne sieci:</translation> <translation id="1094607894174825014">Zażądano operacji odczytu lub zapisu z nieprawidłowym offsetem w: „<ph name="DEVICE_NAME" />”.</translation> -<translation id="109758035718544977">Zakończ wyciszanie stron</translation> <translation id="1097658378307015415">Zanim się zalogujesz, wybierz tryb gościa, aby aktywować sieć <ph name="NETWORK_ID" />.</translation> <translation id="1103523840287552314">Zawsze tłumacz z języka: <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Zatrzymaj</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Korzystaj z internetu w oknie incognito, by nie zapisywać historii przeglądania</translation> <translation id="1213037489357051291">Skonfigurowane odciski palców: <ph name="NUM_FINGERPRINTS" /></translation> <translation id="1215411991991485844">Nowa aplikacja działająca w tle została dodana</translation> -<translation id="1216654534877302979">Wycisz strony</translation> <translation id="1216659994753476700">Nie możemy uzyskać dostępu do Twojego profilu. Pliki i dane zapisane na tym urządzeniu mogły zostać utracone.<ph name="BR" /> <ph name="BR" /> Musisz ponownie skonfigurować profil.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Przechowywanie danych na koncie Dysku Google</translation> <translation id="1288037062697528143">Podświetlenie nocne włączy się automatycznie o zachodzie słońca</translation> <translation id="1288300545283011870">Właściwości syntezy mowy</translation> -<translation id="1293177648337752319">Zakończ wyciszanie strony</translation> <translation id="1293264513303784526">Urządzenie USB-C (lewy port)</translation> <translation id="1293556467332435079">Pliki</translation> <translation id="1296497012903089238">Typ certyfikatu</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Strona główna jest stroną nowej karty</translation> <translation id="1436671784520050284">Kontynuuj konfigurację</translation> <translation id="1436784010935106834">Usunięto</translation> -<translation id="1438632560381091872">Wyłącz wyciszenie kart</translation> <translation id="1442392616396121389">Prefiks routingu</translation> <translation id="144283815522798837">Wybrane elementy: <ph name="NUMBER_OF_ITEMS_SELECTED" /></translation> <translation id="1444628761356461360">Tym urządzeniem zarządza właściciel urządzenia: <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Do urządzenia jest podłączona inna klawiatura niż przy ostatnim wpisywaniu hasła. Może ona próbować przechwycić naciskane klawisze.</translation> <translation id="1567750922576943685">Weryfikacja tożsamości pomaga chronić Twoje dane osobowe</translation> <translation id="1567993339577891801">Konsola JavaScript</translation> -<translation id="1568067597247500137">Wycisz stronę</translation> <translation id="1568323446248056064">Otwórz ustawienia wyświetlacza</translation> <translation id="1572266655485775982">Włączanie Wi-Fi</translation> <translation id="1572585716423026576">Ustaw jako tapetę</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">Podpis X9.62 ECDSA z SHA-1</translation> <translation id="1644574205037202324">Historia</translation> <translation id="1645516838734033527">Aby można było chronić urządzenie <ph name="DEVICE_TYPE" /> przy użyciu funkcji Smart Lock, telefon musi mieć ustawioną blokadę ekranu.</translation> -<translation id="1646102270785326155">Usunięcie tego użytkownika spowoduje trwałe usunięcie wszystkich związanych z nim plików i danych lokalnych. $1 może później zalogować się ponownie.</translation> <translation id="1646982517418478057">Wpisz hasło, by zaszyfrować ten certyfikat</translation> <translation id="164814987133974965">Użytkownik nadzorowany może przeglądać internet zgodnie z Twoimi wytycznymi. Jako jego menedżer możesz: <ph name="BEGIN_BOLD" />zezwalać na dostęp do określonych witryn lub blokować go<ph name="END_BOLD" />, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Kontroluje także to, jaka strona wyświetla się po wyszukiwaniu w omniboksie.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Aby usunąć aplikacje, otwórz Ustawienia > Sklep Google Play > Zarządzaj ustawieniami Androida > Aplikacje lub Menedżer aplikacji. Następnie kliknij aplikację, którą chcesz odinstalować (jeśli to konieczne, przesuń palcem w prawo lub w lewo, by ją znaleźć), a potem kliknij Odinstaluj lub Wyłącz.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Wysyłanie żądania...</translation> -<translation id="1732215134274276513">Odpinanie kart</translation> <translation id="1733383495376208985">Szyfruj synchronizowane dane własnym <ph name="BEGIN_LINK" />hasłem synchronizacji<ph name="END_LINK" />. Nie obejmuje to form płatności ani adresów w Google Pay.</translation> <translation id="1734824808160898225">Program <ph name="PRODUCT_NAME" /> może nie móc sam się aktualizować</translation> <translation id="1736419249208073774">Odkrywaj</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Wszystkie pliki</translation> <translation id="1809734401532861917">Dodaj moje zakładki, historię, hasła i inne ustawienia do profilu <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Podgląd niedostępny</translation> -<translation id="1812631533912615985">Odpinanie kart</translation> <translation id="1813278315230285598">Usługi</translation> <translation id="18139523105317219">Nazwa strony EDI</translation> <translation id="1815083418640426271">Wklej jako zwykły tekst</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Przeglądarką Chrome steruje zautomatyzowane oprogramowanie testowe.</translation> <translation id="2070909990982335904">Nazwy zaczynające się od kropki są zarezerwowane dla systemu. Wybierz inną nazwę.</translation> <translation id="2071393345806050157">Nie ma lokalnego pliku dziennika.</translation> -<translation id="2074527029802029717">Odepnij kartę</translation> <translation id="2075474481720804517">Bateria: <ph name="BATTERY_PERCENTAGE" />%</translation> <translation id="2075959085554270910">Pozwala włączyć lub wyłączyć kliknięcie przez dotknięcie i przeciąganie dotykiem</translation> <translation id="2076269580855484719">Ukryj wtyczkę</translation> @@ -1357,7 +1348,6 @@ <translation id="3045447014237878114">Ta strona automatycznie pobrała wiele plików</translation> <translation id="3046910703532196514">Strona internetowa, kompletna</translation> <translation id="304747341537320566">Mechanizmy syntezy mowy</translation> -<translation id="304826556400666995">Wyłącz wyciszenie kart</translation> <translation id="3053013834507634016">Użycie klucza certyfikatu</translation> <translation id="3057861065630527966">Utwórz kopię zapasową zdjęć i filmów</translation> <translation id="3060379269883947824">Włącz funkcję Przeczytaj na głos</translation> @@ -2343,7 +2333,6 @@ <translation id="4628762811416793313">Konfiguracja kontenera Linuxa nie została ukończona. Spróbuj ponownie.</translation> <translation id="4628948037717959914">Zdjęcie</translation> <translation id="4631887759990505102">Wykonawca</translation> -<translation id="4632483769545853758">Wyłącz wyciszenie karty</translation> <translation id="4633003931260532286">Rozszerzenie wymaga: „<ph name="IMPORT_NAME" />” przynajmniej w wersji „<ph name="IMPORT_VERSION" />”, ale zainstalowana jest tylko wersja „<ph name="INSTALLED_VERSION" />”</translation> <translation id="4634771451598206121">Zaloguj się ponownie</translation> <translation id="4635398712689569051">Strona <ph name="PAGE_NAME" /> jest niedostępna dla gości.</translation> @@ -2408,7 +2397,6 @@ <translation id="4736292055110123391">Synchronizuj zakładki, hasła, historię i inne dane na wszystkich Twoich urządzeniach</translation> <translation id="4737715515457435632">Połącz się z siecią</translation> <translation id="473775607612524610">Aktualizuj</translation> -<translation id="474217410105706308">Wycisz kartę</translation> <translation id="4742746985488890273">Przypnij do półki</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Dowiedz się, jak zaktualizować aplikacje<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Wiadomość tekstowa</translation> @@ -2633,7 +2621,6 @@ <translation id="5094721898978802975">Komunikowanie się ze współpracującymi aplikacjami natywnymi</translation> <translation id="5097002363526479830">Nie udało się połączyć z siecią „<ph name="NAME" />”: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Otwórz wszystkie zakładki</translation> -<translation id="5105855035535475848">Przypinanie kart</translation> <translation id="5108967062857032718">Ustawienia – Usuń aplikacje na Androida</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">&Menedżer zakładek</translation> @@ -2698,7 +2685,6 @@ <translation id="520621735928254154">Błąd importowania certyfikatu</translation> <translation id="5209320130288484488">Nie znaleziono urządzeń</translation> <translation id="5209518306177824490">Odcisk cyfrowy SHA-1</translation> -<translation id="5210365745912300556">Zamknij kartę</translation> <translation id="5213481667492808996">Usługa transmisji danych „<ph name="NAME" />” jest gotowa do użycia</translation> <translation id="5213891612754844763">Pokaż ustawienia serwera proxy</translation> <translation id="521582610500777512">Zdjęcie zostało odrzucone</translation> @@ -2750,7 +2736,6 @@ <translation id="5272654297705279635">Ustawienia niestandardowe</translation> <translation id="5275352920323889391">Pies</translation> <translation id="5275973617553375938">Pliki odzyskane z Dysku Google</translation> -<translation id="527605719918376753">Wycisz kartę</translation> <translation id="527605982717517565">Zawsze zezwalaj na wykonywanie kodu JavaScript w witrynie <ph name="HOST" /></translation> <translation id="5280426389926346830">Utworzyć skrót?</translation> <translation id="528208740344463258">Aby pobrać aplikacje na Androida i ich używać, najpierw musisz zainstalować tę wymaganą aktualizację. Podczas gdy <ph name="DEVICE_TYPE" /> się aktualizuje, nie możesz korzystać z tego urządzenia. Po zakończeniu instalacji <ph name="DEVICE_TYPE" /> uruchomi się ponownie.</translation> @@ -2873,7 +2858,6 @@ <translation id="5449551289610225147">Nieprawidłowe hasło</translation> <translation id="5449588825071916739">Dodaj wszystkie karty do zakładek</translation> <translation id="5449716055534515760">Zamknij o&kno</translation> -<translation id="5453029940327926427">Zamknij karty</translation> <translation id="5454166040603940656">za pomocą <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Nieprawidłowe</translation> <translation id="5457459357461771897">Odczyt i usuwanie zdjęć, muzyki oraz innych multimediów na komputerze</translation> @@ -3338,7 +3322,6 @@ <translation id="6122875415561139701">Nie jest dozwolona operacja zapisu na: „<ph name="DEVICE_NAME" />”.</translation> <translation id="6124650939968185064">To rozszerzenie jest wymagane przez następujące rozszerzenia:</translation> <translation id="6125479973208104919">Musisz jeszcze raz dodać swoje konto na tym urządzeniu <ph name="DEVICE_TYPE" />.</translation> -<translation id="612596694132302162">Zakończ wyciszanie strony</translation> <translation id="6129691635767514872">Wybrane dane zostały usunięte z Chrome i synchronizowanych urządzeń. Inne rodzaje historii przeglądania, takie jak wyszukiwania i aktywność w innych usługach Google, mogą być nadal dostępne na Twoim koncie Google na <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Komentarz do certyfikatu firmy Netscape</translation> <translation id="6129953537138746214">Spacja</translation> @@ -3541,7 +3524,6 @@ <translation id="6436164536244065364">Zobacz w Chrome Web Store</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – odtwarzanie dźwięku</translation> <translation id="6442187272350399447">Świetny</translation> -<translation id="6442697326824312960">Odepnij kartę</translation> <translation id="6444070574980481588">Ustaw datę i godzinę</translation> <translation id="6445450263907939268">Jeśli nie chcesz tych zmian, możesz przywrócić poprzednie ustawienia.</translation> <translation id="6447842834002726250">Pliki cookie</translation> @@ -3744,7 +3726,6 @@ <translation id="6770664076092644100">Zweryfikuj przez NFC</translation> <translation id="6771503742377376720">Jest urzędem certyfikacji</translation> <translation id="6777817260680419853">Przekierowanie zostało zablokowane</translation> -<translation id="6778959797435875428">Zakończ wyciszanie stron</translation> <translation id="677965093459947883">Bardzo mała</translation> <translation id="6780439250949340171">zarządzać innymi ustawieniami</translation> <translation id="6781284683813954823">Link do doodla</translation> @@ -4061,7 +4042,6 @@ <translation id="7257666756905341374">Odczyt danych, które kopiujesz i wklejasz</translation> <translation id="7258697411818564379">Kod PIN został dodany</translation> <translation id="7262004276116528033">Ta usługa logowania pochodzi z domeny <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Zamknij karty</translation> <translation id="7268659760406822741">Dostępne usługi</translation> <translation id="7270858098575133036">Pytaj, gdy strona chce użyć komunikatów systemowych, by uzyskać dostęp do urządzeń MIDI</translation> <translation id="7272674038937250585">Brak opisu</translation> @@ -4251,7 +4231,6 @@ <translation id="7576032389798113292">6 x 4</translation> <translation id="7576690715254076113">Sortuj</translation> <translation id="7576976045740938453">Wystąpił problem z kontem trybu demonstracyjnego.</translation> -<translation id="7579149537961810247">Wycisz strony</translation> <translation id="7580671184200851182">Odtwarzaj ten sam dźwięk na wszystkich głośnikach (dźwięk mono)</translation> <translation id="7581462281756524039">Narzędzie do czyszczenia</translation> <translation id="7582582252461552277">Preferuj tę sieć</translation> @@ -4605,7 +4584,6 @@ <translation id="8068253693380742035">Kliknij, by się zalogować</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Drukuj jako grafikę</translation> -<translation id="8072988827236813198">Przypinanie kart</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Dane aplikacji obejmują wszystkie dane zapisane przez aplikację (zgodnie z ustawieniami programisty). Mogą to być między innymi kontakty, wiadomości i zdjęcia.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Dane kopii zapasowej nie wliczają się do limitu miejsca na Dysku Twojego dziecka.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Możesz wyłączyć tę usługę w Ustawieniach.<ph name="END_PARAGRAPH3" /></translation> @@ -4792,7 +4770,6 @@ <translation id="8368859634510605990">&Otwórz wszystkie zakładki</translation> <translation id="8371695176452482769">Mów teraz</translation> <translation id="8372369524088641025">Błędny klucz WEP</translation> -<translation id="8373553483208508744">Wycisz karty</translation> <translation id="8378714024927312812">Zarządzane przez Twoją organizację</translation> <translation id="8379878387931047019">To urządzenie nie obsługuje typu klucza bezpieczeństwa, o który prosi ta witryna</translation> <translation id="8382913212082956454">Kopiuj adres &e-mail</translation> @@ -4900,7 +4877,6 @@ <translation id="8546930481464505581">Dostosuj pasek dotykowy</translation> <translation id="8547013269961688403">Włącz lupę pełnego ekranu</translation> <translation id="85486688517848470">Przytrzymaj klawisz wyszukiwania, by zmienić działanie klawiszy z górnego rzędu</translation> -<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> @@ -5215,7 +5191,6 @@ <translation id="9038430547971207796">Następnym razem Twój telefon odblokuje urządzenie <ph name="DEVICE_TYPE" />. Funkcję Smart Lock możesz wyłączyć w Ustawieniach.</translation> <translation id="9038649477754266430">Używaj podpowiedzi, by strony ładowały się szybciej</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Wycisz karty</translation> <translation id="9040661932550800571">Zaktualizować hasło do: <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Dostęp do plików lokalnych na tym komputerze został wyłączony przez administratora</translation> <translation id="9042893549633094279">Prywatność i bezpieczeństwo</translation> @@ -5313,7 +5288,6 @@ <translation id="920045321358709304">Szukaj w: <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Opcje blokady ekranu</translation> <translation id="9203398526606335860">&Profilowanie włączone</translation> -<translation id="9203478404496196495">Wyłącz wyciszenie karty</translation> <translation id="9203904171912129171">Wybierz urządzenie</translation> <translation id="9203962528777363226">Administrator tego urządzenia wyłączył możliwość dodawania nowych użytkowników</translation> <translation id="9213073329713032541">Instalacja rozpoczęła się.</translation>
diff --git a/chrome/app/resources/generated_resources_pt-BR.xtb b/chrome/app/resources/generated_resources_pt-BR.xtb index 412ac58..8df753ef 100644 --- a/chrome/app/resources/generated_resources_pt-BR.xtb +++ b/chrome/app/resources/generated_resources_pt-BR.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Pressione ESC para pular (versões não-oficiais apenas).</translation> <translation id="1093457606523402488">Redes visíveis</translation> <translation id="1094607894174825014">A operação de leitura ou escrita foi solicitada com um deslocamento inválido em: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">Parar de ignorar sites</translation> <translation id="1097658378307015415">Antes de fazer login, entre como Visitante para ativar a rede <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Sempre traduzir do <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Parar</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Use a Web sem salvar seu histórico de navegação com uma janela anônima</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> impressões digitais configuradas</translation> <translation id="1215411991991485844">Novo aplicativo de fundo adicionado</translation> -<translation id="1216654534877302979">Ignorar sites</translation> <translation id="1216659994753476700">Não é possível acessar seu perfil. Arquivos e dados armazenados neste dispositivo podem ter sido perdidos.<ph name="BR" /> <ph name="BR" /> Será necessário configurar seu perfil novamente.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Armazenar dados em sua conta do Google Drive</translation> <translation id="1288037062697528143">O Modo noturno será ativado automaticamente ao anoitecer</translation> <translation id="1288300545283011870">Propriedades da fala</translation> -<translation id="1293177648337752319">Parar de ignorar site</translation> <translation id="1293264513303784526">Dispositivo USB-C (porta da esquerda)</translation> <translation id="1293556467332435079">Arquivos</translation> <translation id="1296497012903089238">Tipo de certificado</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">A página inicial é a página "Nova guia"</translation> <translation id="1436671784520050284">Continuar a configuração</translation> <translation id="1436784010935106834">Removido</translation> -<translation id="1438632560381091872">Ativar som das guias</translation> <translation id="1442392616396121389">Prefixo de roteamento</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> selecionado(s)</translation> <translation id="1444628761356461360">Esta configuração é gerenciada pelo proprietário do dispositivo, <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Um teclado diferente foi conectado desde a última vez que você inseriu sua senha. Ele pode estar tentando capturar sua digitação.</translation> <translation id="1567750922576943685">A verificação da sua identidade ajuda a proteger suas informações pessoais</translation> <translation id="1567993339577891801">Console JavaScript</translation> -<translation id="1568067597247500137">Desativar som do site</translation> <translation id="1568323446248056064">Abrir configurações de exibição do dispositivo</translation> <translation id="1572266655485775982">Ativar Wi-Fi</translation> <translation id="1572585716423026576">Definir como plano de fundo</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">Assinatura X9.62 ECDSA com SHA-1</translation> <translation id="1644574205037202324">Histórico</translation> <translation id="1645516838734033527">Para manter seu <ph name="DEVICE_TYPE" /> protegido, o Smart Lock exige um bloqueio de tela no smartphone.</translation> -<translation id="1646102270785326155">Todos os arquivos e dados locais associados a este usuário serão excluídos permanentemente quando o usuário for removido. $1 ainda poderá fazer login mais tarde.</translation> <translation id="1646982517418478057">Digite uma senha para criptografar este certificado</translation> <translation id="164814987133974965">Um usuário supervisionado pode explorar a Web com sua orientação. Como gerenciador de um usuário supervisionado, você pode <ph name="BEGIN_BOLD" />permitir ou proibir<ph name="END_BOLD" /> certos websites, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Controla também qual página deve ser exibida quando você faz uma pesquisa na Omnibox.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Para remover apps, acesse "Config." > "Google Play Store" > "Gerenciar preferências do Android" > "Apps" ou "Gerenciador de apps". Depois, toque no app que você quer desinstalar. Talvez seja necessário deslizar para a direita ou para a esquerda para encontrar o app. Em seguida, toque em "Desinstalar" ou "Desativar".<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Enviando solicitação...</translation> -<translation id="1732215134274276513">Liberar guias</translation> <translation id="1733383495376208985">Criptografar dados sincronizados com sua <ph name="BEGIN_LINK" />senha longa de sincronização<ph name="END_LINK" />. Isso não inclui formas de pagamento e endereços do Google Pay.</translation> <translation id="1734824808160898225">Talvez o <ph name="PRODUCT_NAME" /> não consiga se manter atualizado</translation> <translation id="1736419249208073774">Explorar</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Todos os arquivos</translation> <translation id="1809734401532861917">Adicionar meus favoritos, histórico, senhas e outras configurações a <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Nenhuma visualização disponível</translation> -<translation id="1812631533912615985">Liberar guias</translation> <translation id="1813278315230285598">Serviços</translation> <translation id="18139523105317219">Nome da Parte EDI</translation> <translation id="1815083418640426271">Colar como texto sem formatação</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">O Chrome está sendo controlado por um software de teste automatizado.</translation> <translation id="2070909990982335904">Nomes começando com um ponto estão reservados para o sistema. Favor escolher outro nome.</translation> <translation id="2071393345806050157">Nenhum arquivo de log local.</translation> -<translation id="2074527029802029717">Liberar guia</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% de bateria</translation> <translation id="2075959085554270910">Permite ativar/desativar os recursos tocar para clicar e arrastar com toque</translation> <translation id="2076269580855484719">Ocultar este plug-in</translation> @@ -1357,7 +1348,6 @@ <translation id="3045447014237878114">Este site fez o download de vários arquivos automaticamente</translation> <translation id="3046910703532196514">Página da web, completa</translation> <translation id="304747341537320566">Mecanismos de fala</translation> -<translation id="304826556400666995">Ativar som das guias</translation> <translation id="3053013834507634016">Uso da chave de certificado</translation> <translation id="3057861065630527966">Fazer backup de suas fotos e seus vídeos</translation> <translation id="3060379269883947824">Ativar Selecionar para ouvir</translation> @@ -2343,7 +2333,6 @@ <translation id="4628762811416793313">A configuração do contêiner Linux não foi concluída. Tente novamente.</translation> <translation id="4628948037717959914">Foto</translation> <translation id="4631887759990505102">Artista</translation> -<translation id="4632483769545853758">Ativar o som da guia</translation> <translation id="4633003931260532286">A extensão requer "<ph name="IMPORT_NAME" />" com a versão mínima "<ph name="IMPORT_VERSION" />", mas apenas a versão "<ph name="INSTALLED_VERSION" />" está instalada</translation> <translation id="4634771451598206121">Fazer login novamente...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> não está disponível para usuários visitantes.</translation> @@ -2408,7 +2397,6 @@ <translation id="4736292055110123391">Sincronize favoritos, senhas, histórico e muito mais em todos os seus dispositivos</translation> <translation id="4737715515457435632">Conecte-se a uma rede</translation> <translation id="473775607612524610">Atualizar</translation> -<translation id="474217410105706308">Desativar som da guia</translation> <translation id="4742746985488890273">Fixar na estante</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Saiba como atualizar aplicativos<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Mensagens</translation> @@ -2633,7 +2621,6 @@ <translation id="5094721898978802975">Comunicar-se com aplicativos nativos de colaboração</translation> <translation id="5097002363526479830">Falha na conexão à rede "<ph name="NAME" />": <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Abrir todos os favoritos</translation> -<translation id="5105855035535475848">Fixar guias</translation> <translation id="5108967062857032718">Configurações - Remover apps Android</translation> <translation id="5109044022078737958">Ju</translation> <translation id="5111692334209731439">&Gerenciador de favoritos</translation> @@ -2698,7 +2685,6 @@ <translation id="520621735928254154">Erro ao importar certificado</translation> <translation id="5209320130288484488">Nenhum dispositivo foi encontrado</translation> <translation id="5209518306177824490">Assinatura digital SHA-1</translation> -<translation id="5210365745912300556">Fechar guia</translation> <translation id="5213481667492808996">Seu serviço de dados "<ph name="NAME" />" está pronto para ser usado</translation> <translation id="5213891612754844763">Mostrar configurações de proxy</translation> <translation id="521582610500777512">A foto foi descartada.</translation> @@ -2750,7 +2736,6 @@ <translation id="5272654297705279635">Configurações personalizadas</translation> <translation id="5275352920323889391">Cachorro</translation> <translation id="5275973617553375938">Arquivos recuperados a partir do Google Drive</translation> -<translation id="527605719918376753">Desativar som da guia</translation> <translation id="527605982717517565">Sempre permitir JavaScript em <ph name="HOST" /></translation> <translation id="5280426389926346830">Criar atalho?</translation> <translation id="528208740344463258">Para fazer o download e usar os apps Android, primeiro é necessário instalar esta atualização obrigatória. Enquanto seu <ph name="DEVICE_TYPE" /> estiver sendo atualizado, não será possível usá-lo. O <ph name="DEVICE_TYPE" /> será reiniciado quando a instalação for concluída.</translation> @@ -2873,7 +2858,6 @@ <translation id="5449551289610225147">Senha inválida</translation> <translation id="5449588825071916739">Adicionar todas as guias aos favoritos</translation> <translation id="5449716055534515760">Fechar jan&ela</translation> -<translation id="5453029940327926427">Fechar guias</translation> <translation id="5454166040603940656">com <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Inválidos</translation> <translation id="5457459357461771897">Ler e excluir fotos, músicas e outras mídias do seu computador</translation> @@ -3339,7 +3323,6 @@ <translation id="6122875415561139701">A operação de escrita não é permitida em: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">As extensões a seguir dependem desta extensão:</translation> <translation id="6125479973208104919">Adicione sua conta a esse <ph name="DEVICE_TYPE" /> novamente.</translation> -<translation id="612596694132302162">Parar de ignorar site</translation> <translation id="6129691635767514872">Os dados selecionados foram removidos do Chrome e dos dispositivos sincronizados. É possível que sua Conta do Google tenha outras formas de histórico de navegação, como pesquisas e atividades de outros serviços do Google em <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Comentário do certificado do Netscape</translation> <translation id="6129953537138746214">Espaço</translation> @@ -3543,7 +3526,6 @@ <translation id="6436164536244065364">Visualizar na Chrome Web Store</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - Reprodução de áudio</translation> <translation id="6442187272350399447">Simpatia</translation> -<translation id="6442697326824312960">Liberar guia</translation> <translation id="6444070574980481588">Definir data e hora</translation> <translation id="6445450263907939268">Se você não deseja essas alterações, é possível restaurar as configurações anteriores.</translation> <translation id="6447842834002726250">Cookies</translation> @@ -3746,7 +3728,6 @@ <translation id="6770664076092644100">Verificar por NFC</translation> <translation id="6771503742377376720">É uma Autoridade de certificação</translation> <translation id="6777817260680419853">Redirecionamento bloqueado</translation> -<translation id="6778959797435875428">Parar de ignorar sites</translation> <translation id="677965093459947883">Muito pequeno</translation> <translation id="6780439250949340171">gerenciar outras configurações</translation> <translation id="6781284683813954823">Link do doodle</translation> @@ -4063,7 +4044,6 @@ <translation id="7257666756905341374">Ler dados que você copia e cola</translation> <translation id="7258697411818564379">Seu PIN foi adicionado</translation> <translation id="7262004276116528033">Este serviço de login é hospedado por <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Fechar guias</translation> <translation id="7268659760406822741">Serviços disponíveis</translation> <translation id="7270858098575133036">Perguntar quando um site quiser usar mensagens exclusivas do sistema para acessar dispositivos MIDI</translation> <translation id="7272674038937250585">Nenhuma descrição fornecida</translation> @@ -4253,7 +4233,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">Agrupar</translation> <translation id="7576976045740938453">Ocorreu um problema com a conta do modo de demonstração.</translation> -<translation id="7579149537961810247">Ignorar sites</translation> <translation id="7580671184200851182">Reproduzir o mesmo áudio pelos alto-falantes (áudio mono)</translation> <translation id="7581462281756524039">Uma ferramenta de limpeza</translation> <translation id="7582582252461552277">Preferir esta rede</translation> @@ -4607,7 +4586,6 @@ <translation id="8068253693380742035">Toque para fazer login</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Imprimir como imagem</translation> -<translation id="8072988827236813198">Fixar guias</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Os dados de apps podem ser quaisquer dados que um app tenha salvado (com base nas configurações de desenvolvedores), incluindo dados como contatos, mensagens e fotos.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Os dados de backup não serão contabilizados na cota de armazenamento do Drive do seu filho.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />É possível desativar esse serviço nas configurações.<ph name="END_PARAGRAPH3" /></translation> @@ -4794,7 +4772,6 @@ <translation id="8368859634510605990">&Abrir todos os favoritos</translation> <translation id="8371695176452482769">Fale agora</translation> <translation id="8372369524088641025">Chave WEP incorreta</translation> -<translation id="8373553483208508744">Desativar som das guias</translation> <translation id="8378714024927312812">Gerenciado pela sua organização</translation> <translation id="8379878387931047019">Este dispositivo não é compatível com o tipo de chave de segurança solicitado por este site</translation> <translation id="8382913212082956454">Copiar &endereço de e-mail</translation> @@ -4902,7 +4879,6 @@ <translation id="8546930481464505581">Personalizar barra de toque</translation> <translation id="8547013269961688403">Ativar lupa de tela cheia</translation> <translation id="85486688517848470">Mantenha pressionada a tecla "Pesquisar" para alternar o comportamento das teclas de função</translation> -<translation id="855081842937141170">Fixar guia</translation> <translation id="8551388862522347954">Licenças</translation> <translation id="8553342806078037065">Gerenciar outras pessoas</translation> <translation id="8554899698005018844">Sem idioma</translation> @@ -5217,7 +5193,6 @@ <translation id="9038430547971207796">Na próxima vez, o smartphone desbloqueará seu <ph name="DEVICE_TYPE" />. Desative o Smart Lock nas configurações.</translation> <translation id="9038649477754266430">Usar um serviço de previsão para carregar páginas mais rapidamente</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Desativar som das guias</translation> <translation id="9040661932550800571">Atualizar senha para <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">O acesso a arquivos locais no seu computador foi desativado pelo administrador</translation> <translation id="9042893549633094279">Privacidade e segurança</translation> @@ -5315,7 +5290,6 @@ <translation id="920045321358709304">Pesquisar <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Opções de bloqueio de tela</translation> <translation id="9203398526606335860">&Criação de perfil ativada</translation> -<translation id="9203478404496196495">Ativar o som da guia</translation> <translation id="9203904171912129171">Selecione um dispositivo</translation> <translation id="9203962528777363226">O administrador deste dispositivo desativou a adição de novos usuários</translation> <translation id="9213073329713032541">Instalação iniciada.</translation>
diff --git a/chrome/app/resources/generated_resources_pt-PT.xtb b/chrome/app/resources/generated_resources_pt-PT.xtb index 6f1aad3..f9239c0 100644 --- a/chrome/app/resources/generated_resources_pt-PT.xtb +++ b/chrome/app/resources/generated_resources_pt-PT.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Prima ESCAPE para ignorar (apenas nas compilações não oficiais).</translation> <translation id="1093457606523402488">Redes visíveis</translation> <translation id="1094607894174825014">Foi solicitada uma operação de leitura ou de escrita com um desvio inválido em: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">Reativar som dos sites</translation> <translation id="1097658378307015415">Antes de iniciar sessão, entre como Convidado para ativar a rede <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Traduzir sempre <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Parar</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Navegue na Web sem guardar o seu histórico de navegação com uma janela de navegação anónima</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> impressões digitais configuradas</translation> <translation id="1215411991991485844">Nova aplicação de segundo plano adicionada</translation> -<translation id="1216654534877302979">Desativar som dos sites</translation> <translation id="1216659994753476700">Não é possível aceder ao seu perfil. Os ficheiros e os dados armazenados neste dispositivo podem ter sido perdidos.<ph name="BR" /> <ph name="BR" /> Tem de configurar novamente o seu perfil.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Armazenar dados na sua conta Google Drive</translation> <translation id="1288037062697528143">A Luz noturna irá ativar-se automaticamente ao pôr-do-sol.</translation> <translation id="1288300545283011870">Propriedades de voz</translation> -<translation id="1293177648337752319">Reativar som do site</translation> <translation id="1293264513303784526">Dispositivo USB-C (porta esquerda)</translation> <translation id="1293556467332435079">Ficheiros</translation> <translation id="1296497012903089238">Tipo de certificado</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">A Página inicial é a página Novo separador</translation> <translation id="1436671784520050284">Continuar configuração</translation> <translation id="1436784010935106834">Removido</translation> -<translation id="1438632560381091872">Reativar som dos separadores</translation> <translation id="1442392616396121389">Prefixo de encaminhamento</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> selecionados</translation> <translation id="1444628761356461360">Esta definição é gerida pelo proprietário do dispositivo, <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Foi ligado um teclado diferente desde a última vez que introduziu a palavra-passe. É possível que esteja a tentar roubar os seus toques de teclas.</translation> <translation id="1567750922576943685">A validação da sua identidade ajuda a proteger as suas informações pessoais.</translation> <translation id="1567993339577891801">Consola de JavaScript</translation> -<translation id="1568067597247500137">Desativar som do site</translation> <translation id="1568323446248056064">Abrir definições do dispositivo de visualização</translation> <translation id="1572266655485775982">Ativar Wi-Fi</translation> <translation id="1572585716423026576">Definir como imagem de fundo</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">Assinatura X9.62 ECDSA com SHA-1</translation> <translation id="1644574205037202324">Histórico</translation> <translation id="1645516838734033527">Para manter o seu <ph name="DEVICE_TYPE" /> protegido, o Smart Lock requer um bloqueio de ecrã no telemóvel.</translation> -<translation id="1646102270785326155">Todos os ficheiros e dados locais associados a este utilizador são permanentemente eliminados depois da sua remoção. $2 pode ainda iniciar sessão mais tarde.</translation> <translation id="1646982517418478057">Introduza uma palavra-passe para encriptar este certificado</translation> <translation id="164814987133974965">Um utilizador supervisionado pode explorar a Web com a sua orientação. Enquanto gestor de um utilizador supervisionado, pode <ph name="BEGIN_BOLD" />permitir ou proibir<ph name="END_BOLD" /> determinados Sites, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Também controla a página apresentada quando pesquisa a partir da Caixa geral.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Para remover aplicações, aceda a Definições > Google Play Store > Gerir as preferências do Android > Aplicações ou Gestor de aplicações. Toque na aplicação que pretende desinstalar (pode ter de deslizar rapidamente para a direita ou para a esquerda para encontrar a aplicação). Em seguida, toque em Desinstalar ou em Desativar.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">A enviar pedido...</translation> -<translation id="1732215134274276513">Soltar separdores</translation> <translation id="1733383495376208985">Encriptar dados sincronizados com a sua própria <ph name="BEGIN_LINK" />frase de acesso de sincronização<ph name="END_LINK" />. Não estão incluídos métodos de pagamento e endereços do Google Pay.</translation> <translation id="1734824808160898225">O <ph name="PRODUCT_NAME" /> pode não conseguir manter-se atualizado.</translation> <translation id="1736419249208073774">Explorar</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Todos os ficheiros</translation> <translation id="1809734401532861917">Adicionar os marcadores, o histórico, as palavras-passe e outras definições a <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Pré-visualização não disponível</translation> -<translation id="1812631533912615985">Soltar separadores</translation> <translation id="1813278315230285598">Serviços</translation> <translation id="18139523105317219">Nome da parte EDI</translation> <translation id="1815083418640426271">Colar como Texto Simples</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">O Chrome está a ser controlado pelo software de teste automatizado.</translation> <translation id="2070909990982335904">Os nomes que começam por ponto estão reservados para o sistema. Escolha outro nome.</translation> <translation id="2071393345806050157">Nenhum ficheiro de registo local.</translation> -<translation id="2074527029802029717">Desbloquear o separador</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% de bateria</translation> <translation id="2075959085554270910">Permite-lhe ativar/desativar a funcionalidade tocar para clicar e arrastamento através do toque.</translation> <translation id="2076269580855484719">Ocultar este plug-in</translation> @@ -1357,7 +1348,6 @@ <translation id="3045447014237878114">Este site transferiu vários ficheiros automaticamente</translation> <translation id="3046910703532196514">Página Web, Completa</translation> <translation id="304747341537320566">Motores de voz</translation> -<translation id="304826556400666995">Reativar Som dos Separadores</translation> <translation id="3053013834507634016">Utilização de chave de certificado</translation> <translation id="3057861065630527966">Fazer uma cópia de segurança de fotos e vídeos</translation> <translation id="3060379269883947824">Ativar Selecionar para ativar voz</translation> @@ -2343,7 +2333,6 @@ <translation id="4628762811416793313">A configuração do contentor do Linux não foi concluída. Tente novamente.</translation> <translation id="4628948037717959914">Fotografia</translation> <translation id="4631887759990505102">Artista</translation> -<translation id="4632483769545853758">Reativar o Som do Separador</translation> <translation id="4633003931260532286">A extensão requer "<ph name="IMPORT_NAME" />" com, pelo menos, a versão "<ph name="IMPORT_VERSION" />", mas apenas está instalada a versão "<ph name="INSTALLED_VERSION" />".</translation> <translation id="4634771451598206121">Iniciar sessão novamente...</translation> <translation id="4635398712689569051">A página <ph name="PAGE_NAME" /> não está disponível para os utilizadores convidados.</translation> @@ -2408,7 +2397,6 @@ <translation id="4736292055110123391">Sincronizar os seus marcadores, palavras-passe, histórico e muito mais em todos os seus dispositivos</translation> <translation id="4737715515457435632">Ligue-se a uma rede</translation> <translation id="473775607612524610">Atualizar</translation> -<translation id="474217410105706308">Desativar Som do Separador</translation> <translation id="4742746985488890273">Afixar na prateleira</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Saiba como atualizar aplicações<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Mensagens</translation> @@ -2633,7 +2621,6 @@ <translation id="5094721898978802975">Comunicar com aplicações nativas cooperantes</translation> <translation id="5097002363526479830">Falha ao ligar à rede "<ph name="NAME" />": <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Abrir todos os marcadores</translation> -<translation id="5105855035535475848">Fixar separadores</translation> <translation id="5108967062857032718">Definições – Remover aplicações para Android</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">&Gestor de Marcadores</translation> @@ -2698,7 +2685,6 @@ <translation id="520621735928254154">Erro de importação do certificado</translation> <translation id="5209320130288484488">Não foram encontrados aparelhos</translation> <translation id="5209518306177824490">Impressão digital SHA-1</translation> -<translation id="5210365745912300556">Fechar separador</translation> <translation id="5213481667492808996">O serviço de dados de "<ph name="NAME" />" está pronto a ser utilizado.</translation> <translation id="5213891612754844763">Mostrar definições de proxy</translation> <translation id="521582610500777512">A foto foi rejeitada</translation> @@ -2750,7 +2736,6 @@ <translation id="5272654297705279635">Definições personalizadas</translation> <translation id="5275352920323889391">Cão</translation> <translation id="5275973617553375938">Ficheiros recuperados do Google Drive</translation> -<translation id="527605719918376753">Desativar som do separador</translation> <translation id="527605982717517565">Permitir sempre JavaScript em <ph name="HOST" /></translation> <translation id="5280426389926346830">Pretende criar um atalho?</translation> <translation id="528208740344463258">Para transferir e utilizar aplicações para Android, tem de instalar primeiro esta atualização obrigatória. Enquanto o seu <ph name="DEVICE_TYPE" /> estiver a ser atualizado, não o pode utilizar. Quando a instalação estiver concluída, o <ph name="DEVICE_TYPE" /> será reiniciado.</translation> @@ -2873,7 +2858,6 @@ <translation id="5449551289610225147">Palavra-passe inválida</translation> <translation id="5449588825071916739">Adicionar Todos os Separadores aos Marcadores</translation> <translation id="5449716055534515760">Fechar &Janela</translation> -<translation id="5453029940327926427">Fechar separadores</translation> <translation id="5454166040603940656">com <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Inválido</translation> <translation id="5457459357461771897">Ler e eliminar fotos, música e outros elementos multimédia a partir do computador</translation> @@ -3339,7 +3323,6 @@ <translation id="6122875415561139701">A operação de escrita não é permitida em: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">As seguintes extensões dependem desta extensão:</translation> <translation id="6125479973208104919">Infelizmente, tem de adicionar novamente a sua conta a este <ph name="DEVICE_TYPE" />.</translation> -<translation id="612596694132302162">Reativar som do site</translation> <translation id="6129691635767514872">Os dados selecionados foram removidos do Chrome e dos dispositivos sincronizados. A sua Conta Google pode ter outras formas do histórico de navegação, tais como as pesquisas e a atividade de outros serviços Google em <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Comentário do certificado Netscape</translation> <translation id="6129953537138746214">Espaço</translation> @@ -3542,7 +3525,6 @@ <translation id="6436164536244065364">Ver na Web Store</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – áudio em reprodução</translation> <translation id="6442187272350399447">Fantástico</translation> -<translation id="6442697326824312960">Remover separador</translation> <translation id="6444070574980481588">Definir data e hora</translation> <translation id="6445450263907939268">Se não pretendia efetuar estas alterações, pode restaurar as definições anteriores.</translation> <translation id="6447842834002726250">Cookies</translation> @@ -3745,7 +3727,6 @@ <translation id="6770664076092644100">Validar através de NFC</translation> <translation id="6771503742377376720">É uma autoridade de certificação</translation> <translation id="6777817260680419853">Redirecionamento bloqueado</translation> -<translation id="6778959797435875428">Reativar som dos sites</translation> <translation id="677965093459947883">Muito pequeno</translation> <translation id="6780439250949340171">gerir outras definições</translation> <translation id="6781284683813954823">Link do doodle</translation> @@ -4062,7 +4043,6 @@ <translation id="7257666756905341374">Ler dados que copia e cola</translation> <translation id="7258697411818564379">O seu PIN foi adicionado</translation> <translation id="7262004276116528033">Este serviço de início de sessão é alojado por <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Fechar separadores</translation> <translation id="7268659760406822741">Serviços disponíveis</translation> <translation id="7270858098575133036">Perguntar quando um site pretender utilizar mensagens exclusivas do sistema para aceder a dispositivos MIDI</translation> <translation id="7272674038937250585">Nenhuma descrição fornecida</translation> @@ -4252,7 +4232,6 @@ <translation id="7576032389798113292">6 x 4</translation> <translation id="7576690715254076113">Agrupar</translation> <translation id="7576976045740938453">Ocorreu um problema com a conta no modo de demonstração.</translation> -<translation id="7579149537961810247">Desativar som dos sites</translation> <translation id="7580671184200851182">Reproduzir o mesmo áudio em todas as colunas (áudio mono)</translation> <translation id="7581462281756524039">Uma ferramenta de limpeza</translation> <translation id="7582582252461552277">Preferir esta rede</translation> @@ -4606,7 +4585,6 @@ <translation id="8068253693380742035">Toque para iniciar sessão</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Imprimir como imagem</translation> -<translation id="8072988827236813198">Fixar Separadores</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Os dados de aplicações podem ser quaisquer dados que uma aplicação tenha guardado (com base nas definições do programador), incluindo dados como contactos, mensagens e fotos.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Os dados da cópia de segurança não são contabilizados para a quota do armazenamento no Drive da criança.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Pode desativar este serviço nas Definições.<ph name="END_PARAGRAPH3" /></translation> @@ -4791,7 +4769,6 @@ <translation id="8368859634510605990">&Abrir todos os marcadores</translation> <translation id="8371695176452482769">Falar agora</translation> <translation id="8372369524088641025">Chave WEP incorrecta</translation> -<translation id="8373553483208508744">Desativar som dos separadores</translation> <translation id="8378714024927312812">Gerido pela sua entidade</translation> <translation id="8379878387931047019">Este dispositivo não suporta o tipo de chave de segurança necessário para este Website.</translation> <translation id="8382913212082956454">Copiar &endereço de email</translation> @@ -4899,7 +4876,6 @@ <translation id="8546930481464505581">Personalizar a barra tátil</translation> <translation id="8547013269961688403">Ativar lupa de ecrã inteiro</translation> <translation id="85486688517848470">Mantenha premida a tecla Pesquisar para alterar o comportamento das teclas da linha superior</translation> -<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> @@ -5214,7 +5190,6 @@ <translation id="9038430547971207796">Da próxima vez, o telemóvel irá desbloquear o <ph name="DEVICE_TYPE" />. Desative o Smart Lock nas Definições.</translation> <translation id="9038649477754266430">Utilizar um serviço de previsão para carregar páginas mais rapidamente</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Desativar Som dos Separadores</translation> <translation id="9040661932550800571">Pretende atualizar a palavra-passe para <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">O acesso a ficheiros locais no seu computador foi desativado pelo seu administrador.</translation> <translation id="9042893549633094279">Privacidade e segurança</translation> @@ -5312,7 +5287,6 @@ <translation id="920045321358709304">Pesquisar no <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Opções do bloqueio de ecrã</translation> <translation id="9203398526606335860">Criação de &perfis ativada</translation> -<translation id="9203478404496196495">Reativar som do separador</translation> <translation id="9203904171912129171">Selecionar um dispositivo</translation> <translation id="9203962528777363226">O gestor deste dispositivo desativou a adição de novos utilizadores</translation> <translation id="9213073329713032541">A instalação foi iniciada com êxito.</translation>
diff --git a/chrome/app/resources/generated_resources_ro.xtb b/chrome/app/resources/generated_resources_ro.xtb index 2f4edada..fd734c6 100644 --- a/chrome/app/resources/generated_resources_ro.xtb +++ b/chrome/app/resources/generated_resources_ro.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Apăsați pe ESCAPE pentru a ignora (numai versiunile neoficiale).</translation> <translation id="1093457606523402488">Rețele vizibile:</translation> <translation id="1094607894174825014">Operațiunea de citire sau de scriere a fost solicitată cu un decalaj nevalid pe: „<ph name="DEVICE_NAME" />”.</translation> -<translation id="109758035718544977">Activează sunetul pentru site-uri</translation> <translation id="1097658378307015415">Înainte de a vă conecta, începeți o sesiune pentru invitați pentru activarea rețelei <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Tradu întotdeauna din <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Oprește</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Folosește internetul fără a salva istoricul de navigare, într-o fereastră incognito</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> amprente configurate</translation> <translation id="1215411991991485844">Nouă aplicație de fundal adăugată</translation> -<translation id="1216654534877302979">Dezactivează sunetul pentru site-uri</translation> <translation id="1216659994753476700">Ne pare rău. Nu îți putem accesa profilul. Este posibil ca fișierele și datele stocate pe acest dispozitiv să se fi pierdut.<ph name="BR" /> <ph name="BR" /> Va trebui să îți configurezi profilul din nou.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Stocați datele în contul Google Drive</translation> <translation id="1288037062697528143">Lumina de noapte se va activa automat la apus</translation> <translation id="1288300545283011870">Proprietăți pentru vorbire</translation> -<translation id="1293177648337752319">Activează sunetul pentru site</translation> <translation id="1293264513303784526">Dispozitiv USB-C (portul din stânga)</translation> <translation id="1293556467332435079">Fișiere</translation> <translation id="1296497012903089238">Tip de certificat</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Pagina de pornire este pagina Filă nouă</translation> <translation id="1436671784520050284">Continuă configurarea</translation> <translation id="1436784010935106834">Eliminat</translation> -<translation id="1438632560381091872">Activează sunetul filelor</translation> <translation id="1442392616396121389">Prefix de redirecționare</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> selectate</translation> <translation id="1444628761356461360">Această setare este gestionată de proprietarul dispozitivului, <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">A fost conectată o altă tastatură după ce ai introdus parola ultima dată. Aceasta ar putea încerca să înregistreze ce taste apeși.</translation> <translation id="1567750922576943685">Confirmarea identității te ajută să-ți protejezi informațiile cu caracter personal</translation> <translation id="1567993339577891801">Consolă JavaScript</translation> -<translation id="1568067597247500137">Dezactivează sunetul pentru site</translation> <translation id="1568323446248056064">Deschide setările dispozitivului privind afișajul</translation> <translation id="1572266655485775982">Activează Wi-Fi</translation> <translation id="1572585716423026576">Setează ca imagine de fundal</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">Semnătură X9.62 ECDSA cu SHA-1</translation> <translation id="1644574205037202324">Istoric</translation> <translation id="1645516838734033527">Pentru a proteja dispozitivul <ph name="DEVICE_TYPE" />, Smart Lock necesită o blocare a ecranului pe telefon.</translation> -<translation id="1646102270785326155">După eliminarea utilizatorului, toate fișierele și datele locale asociate acestuia vor fi șterse definitiv. $1 se poate conecta în continuare mai târziu.</translation> <translation id="1646982517418478057">Introdu o parolă pentru a cripta acest certificat</translation> <translation id="164814987133974965">Un utilizator monitorizat poate naviga pe web sub îndrumarea dvs. În calitate de manager al unui utilizator monitorizat, puteți: <ph name="BEGIN_BOLD" />să permiteți sau să restricționați<ph name="END_BOLD" /> accesul la anumite site-uri; @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Stabilește și ce pagină se afișează când căutați din caseta polivalentă.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Pentru a elimina aplicații, accesează Setări > Magazin Google Play > Gestionează preferințele Android > Aplicații sau Manager de aplicații. Apoi atinge aplicația pe care dorești să o dezinstalezi (poate fi necesar să glisezi la dreapta sau la stânga pentru a găsi aplicația). Apoi, atinge Dezinstalează sau Dezactivează.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Se trimite solicitarea...</translation> -<translation id="1732215134274276513">Anulează fixarea filelor</translation> <translation id="1733383495376208985">Criptează datele sincronizate cu propria <ph name="BEGIN_LINK" />expresie de acces pentru sincronizare<ph name="END_LINK" />. Acest lucru nu este valabil și pentru metodele de plată și adresele din Google Pay.</translation> <translation id="1734824808160898225">Este posibil ca <ph name="PRODUCT_NAME" /> să nu se poată actualiza</translation> <translation id="1736419249208073774">Explorează</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Toate fișierele</translation> <translation id="1809734401532861917">Adaugă marcajele, istoricul, parolele și alte setări în <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Nicio previzualizare disponibilă</translation> -<translation id="1812631533912615985">Anulează fixarea filelor</translation> <translation id="1813278315230285598">Servicii</translation> <translation id="18139523105317219">Nume parte EDI</translation> <translation id="1815083418640426271">Inserați ca text simplu</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chrome este controlat de un software de testare automată.</translation> <translation id="2070909990982335904">Numele care încep cu punct sunt rezervate pentru sistem. Alege alt nume.</translation> <translation id="2071393345806050157">Niciun fișier jurnal local.</translation> -<translation id="2074527029802029717">Anulează fixarea filei</translation> <translation id="2075474481720804517">Nivelul bateriei: <ph name="BATTERY_PERCENTAGE" />%</translation> <translation id="2075959085554270910">Permite activarea/dezactivarea funcțiilor „Atinge pentru clic” și „Tragere prin atingere”</translation> <translation id="2076269580855484719">Ascunde acest plugin</translation> @@ -773,6 +764,7 @@ <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> +<translation id="2162155940152307086">Sincronizarea va porni după ce părăsești setările pentru sincronizare</translation> <translation id="2163470535490402084">Accesează internetul pentru a te conecta pe dispozitivul tău <ph name="DEVICE_TYPE" />.</translation> <translation id="2166369534954157698">Vând muzică de jazz și haine de bun-gust în New York și Quebec, la preț fix.</translation> <translation id="2169062631698640254">Conectați-vă oricum</translation> @@ -783,6 +775,7 @@ <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> <translation id="218070003709087997">Precizează un număr de exemplare pentru printare (de la 1 la 999).</translation> +<translation id="2182253583899676504">Textul pe care îl introduci în câmpurile de text va fi trimis la Google.</translation> <translation id="2184515124301515068">Permite Chrome să aleagă când site-urile pot reda sunet (recomandat)</translation> <translation id="2187895286714876935">Eroare de import a certificatului serverului</translation> <translation id="2187906491731510095">Extensiile au fost actualizate</translation> @@ -794,7 +787,9 @@ <translation id="2192505247865591433">De la:</translation> <translation id="2193365732679659387">Setări privind încrederea</translation> <translation id="2195729137168608510">Protecție e-mail</translation> +<translation id="2198757192731523470">Google poate folosi istoricul pentru a personaliza Căutarea, anunțurile și alte servicii Google.</translation> <translation id="2199298570273670671">Eroare</translation> +<translation id="2199719347983604670">Datele din Sincronizarea Chrome</translation> <translation id="2200094388063410062">E-mail</translation> <translation id="2200356397587687044">Chrome are nevoie de permisiune pentru a continua</translation> <translation id="2200603218210188859">Preferințe dispozitiv USB</translation> @@ -1252,6 +1247,7 @@ <translation id="2889064240420137087">Deschide linkul cu...</translation> <translation id="2889925978073739256">Continuă blocarea pluginurilor scoase din mediul de testare</translation> <translation id="2893168226686371498">Browserul prestabilit</translation> +<translation id="2895734772884435517">Poți personaliza aceste setări oricând.</translation> <translation id="289644616180464099">Cardul SIM este blocat</translation> <translation id="289695669188700754">ID cheie: <ph name="KEY_ID" /></translation> <translation id="2897878306272793870">Sunteți sigur că doriți să deschideți <ph name="TAB_COUNT" /> (de) file?</translation> @@ -1352,7 +1348,6 @@ <translation id="3045447014237878114">Acest site a descărcat automat mai multe fișiere</translation> <translation id="3046910703532196514">Pagina web, completă</translation> <translation id="304747341537320566">Motoare de vorbire</translation> -<translation id="304826556400666995">Activează sunetul filelor</translation> <translation id="3053013834507634016">Folosirea cheii de certificat</translation> <translation id="3057861065630527966">Fă backup pentru fotografii și videoclipuri</translation> <translation id="3060379269883947824">Activează „Selectează și ascultă”</translation> @@ -1721,6 +1716,7 @@ <translation id="3636096452488277381">Bună ziua, <ph name="USER_GIVEN_NAME" />.</translation> <translation id="3636766455281737684"><ph name="PERCENTAGE" />% – Timp rămas: <ph name="TIME" /></translation> <translation id="3637682276779847508">Cardul SIM va fi dezactivat definitiv dacă nu vei introduce cheia corectă de deblocare a codului PIN.</translation> +<translation id="363863692969456324">Corectează erorile de ortografie cu verificarea ortografiei îmbunătățită</translation> <translation id="3640214691812501263">Adaugi „<ph name="EXTENSION_NAME" />” pentru <ph name="USER_NAME" />?</translation> <translation id="3644896802912593514">Lățime</translation> <translation id="3645372836428131288">Mută ușor pentru a înregistra o altă parte a amprentei</translation> @@ -2153,6 +2149,7 @@ <translation id="4310139701823742692">Fișierul are un format incorect. Verifică fișierul PPD și încearcă din nou.</translation> <translation id="431076611119798497">&Detalii</translation> <translation id="4312866146174492540">Blochează (în mod prestabilit)</translation> +<translation id="4314815835985389558">Gestionează sincronizarea</translation> <translation id="4316850752623536204">Site-ul dezvoltatorului</translation> <translation id="4320177379694898372">Fără conexiune la internet</translation> <translation id="4320948194796820126">Adaugă un marcaj la e-mail</translation> @@ -2232,6 +2229,7 @@ <translation id="4450974146388585462">Diagnosticați</translation> <translation id="4451757071857432900">Blocate pe site-uri care afișează anunțuri deranjante sau înșelătoare (recomandat)</translation> <translation id="4453946976636652378">Caută <ph name="SEARCH_ENGINE_NAME" /> sau introdu o adresă URL</translation> +<translation id="4461835665417498653">Trimite la Google anumite informații despre sistem și conținutul paginii, anonim.</translation> <translation id="4462159676511157176">Servere de nume personalizate</translation> <translation id="4467101674048705704">Extinde <ph name="FOLDER_NAME" /></translation> <translation id="4469477701382819144">Blocate pe site-urile care afișează anunțuri deranjante sau înșelătoare</translation> @@ -2335,7 +2333,6 @@ <translation id="4628762811416793313">Configurarea containerului Linux nu s-a finalizat. Încearcă din nou.</translation> <translation id="4628948037717959914">Fotografie</translation> <translation id="4631887759990505102">Artist</translation> -<translation id="4632483769545853758">Activează sunetul filei</translation> <translation id="4633003931260532286">Extensia necesită „<ph name="IMPORT_NAME" />” cu versiunea minimă „<ph name="IMPORT_VERSION" />”, dar numai versiunea „<ph name="INSTALLED_VERSION" />” este instalată</translation> <translation id="4634771451598206121">Conectați-vă din nou...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> nu este disponibilă pentru utilizatorii invitați.</translation> @@ -2397,9 +2394,9 @@ <translation id="4735265153267957659">Introdu parola pentru a activa Smart Lock. Data viitoare, telefonul tău va debloca dispozitivul <ph name="DEVICE_TYPE" />. Dezactivează Smart Lock din Setări.</translation> <translation id="473546211690256853">Acest cont este administrat de <ph name="DOMAIN" /></translation> <translation id="4735803855089279419">Sistemul nu a stabilit identificatorii de dispozitiv pentru acest dispozitiv.</translation> +<translation id="4736292055110123391">Sincronizează marcajele, parolele, istoricul și alte date, pe toate dispozitivele</translation> <translation id="4737715515457435632">Conectează-te la o rețea</translation> <translation id="473775607612524610">Actualizează</translation> -<translation id="474217410105706308">Dezactivează sunetul filei</translation> <translation id="4742746985488890273">Fixați în raft</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Află cum să actualizezi aplicații<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Mesaje</translation> @@ -2624,7 +2621,6 @@ <translation id="5094721898978802975">Comunicarea cu aplicațiile native cooperante</translation> <translation id="5097002363526479830">A eșuat conectarea la rețeaua „<ph name="NAME" />”: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Deschide toate marcajele</translation> -<translation id="5105855035535475848">Fixează file</translation> <translation id="5108967062857032718">Setări – Elimină aplicațiile Android</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">&Manager de marcaje</translation> @@ -2689,7 +2685,6 @@ <translation id="520621735928254154">Eroare la importul certificatului</translation> <translation id="5209320130288484488">Nu s-a găsit niciun dispozitiv</translation> <translation id="5209518306177824490">Amprentă digitală SHA-1</translation> -<translation id="5210365745912300556">Închide fila</translation> <translation id="5213481667492808996">Serviciul de date „<ph name="NAME" />” este gata de utilizare.</translation> <translation id="5213891612754844763">Afișează setările de proxy</translation> <translation id="521582610500777512">Fotografia a fost ștearsă</translation> @@ -2738,9 +2733,9 @@ <translation id="5266113311903163739">Eroare la importarea Autorității de certificare</translation> <translation id="5269977353971873915">Printarea a eșuat</translation> <translation id="5270167208902136840">Afișează încă <ph name="NUMBER_OF_MORE_APPS" /> aplicații</translation> +<translation id="5272654297705279635">Setări personalizate</translation> <translation id="5275352920323889391">Câine</translation> <translation id="5275973617553375938">Fișiere recuperate din Google Drive</translation> -<translation id="527605719918376753">Dezactivează sunetul filei</translation> <translation id="527605982717517565">Permite întotdeauna JavaScript pe <ph name="HOST" /></translation> <translation id="5280426389926346830">Creezi o comandă rapidă?</translation> <translation id="528208740344463258">Ca să descarci și să folosești aplicații Android, mai întâi trebuie să instalezi această actualizare obligatorie. În timp ce dispozitivul <ph name="DEVICE_TYPE" /> se actualizează, nu îl poți folosi. Dispozitivul <ph name="DEVICE_TYPE" /> va reporni după ce se finalizează instalarea.</translation> @@ -2863,7 +2858,6 @@ <translation id="5449551289610225147">Parolă nevalidă</translation> <translation id="5449588825071916739">Marcați toate filele</translation> <translation id="5449716055534515760">Închide fe&reastra</translation> -<translation id="5453029940327926427">Închide filele</translation> <translation id="5454166040603940656">cu <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Nevalide</translation> <translation id="5457459357461771897">Citește și șterge fotografii, muzică și alte tipuri de conținut media de pe computer</translation> @@ -3328,7 +3322,6 @@ <translation id="6122875415561139701">Operațiunea de scriere nu este permisă pe: „<ph name="DEVICE_NAME" />”.</translation> <translation id="6124650939968185064">De această extensie depind următoarele extensii:</translation> <translation id="6125479973208104919">Din păcate, va trebui să îți adaugi din nou contul pe acest dispozitiv <ph name="DEVICE_TYPE" />.</translation> -<translation id="612596694132302162">Activează sunetul pentru site</translation> <translation id="6129691635767514872">Datele selectate au fost eliminate din Chrome și de pe dispozitivele sincronizate. Contul Google poate să ofere alte forme ale istoricului de navigare, cum ar fi căutările și activitatea din alte servicii Google, la <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Comentariu certificat Netscape</translation> <translation id="6129953537138746214">Spațiu</translation> @@ -3531,7 +3524,6 @@ <translation id="6436164536244065364">Vizualizați în Magazinul web Chrome</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – se redă sunet</translation> <translation id="6442187272350399447">Extraordinar</translation> -<translation id="6442697326824312960">Anulează fixarea filei</translation> <translation id="6444070574980481588">Setați data și ora</translation> <translation id="6445450263907939268">Dacă nu doriți aceste modificări, puteți restabili setările anterioare.</translation> <translation id="6447842834002726250">Cookie-uri</translation> @@ -3734,7 +3726,6 @@ <translation id="6770664076092644100">Confirmă prin NFC</translation> <translation id="6771503742377376720">Este o Autoritate de certificare</translation> <translation id="6777817260680419853">Redirecționarea a fost blocată</translation> -<translation id="6778959797435875428">Activează sunetul pentru site-uri</translation> <translation id="677965093459947883">Foarte mică</translation> <translation id="6780439250949340171">gestionați alte setări</translation> <translation id="6781284683813954823">Link Doodle</translation> @@ -4051,7 +4042,6 @@ <translation id="7257666756905341374">Citește datele pe care le copiezi și le inserezi</translation> <translation id="7258697411818564379">Codul PIN a fost adăugat</translation> <translation id="7262004276116528033">Acest serviciu de conectare este găzduit de <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Închide filele</translation> <translation id="7268659760406822741">Servicii disponibile</translation> <translation id="7270858098575133036">Întreabă-mă când un site dorește să utilizeze mesajele rezervate sistemului ca să acceseze dispozitivele MIDI</translation> <translation id="7272674038937250585">Nu a fost oferită o descriere</translation> @@ -4241,7 +4231,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">Colaționează</translation> <translation id="7576976045740938453">A apărut o problemă la contul modului demo.</translation> -<translation id="7579149537961810247">Dezactivează sunetul pentru site-uri</translation> <translation id="7580671184200851182">Redă același conținut audio în toate difuzoarele (audio mono)</translation> <translation id="7581462281756524039">Un instrument de curățare</translation> <translation id="7582582252461552277">Prefer această rețea</translation> @@ -4595,7 +4584,6 @@ <translation id="8068253693380742035">Atinge pentru a te conecta</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Printează ca imagine</translation> -<translation id="8072988827236813198">Fixează file</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Datele unei aplicații pot fi orice date pe care le-a salvat aplicația (în funcție de setările dezvoltatorului), inclusiv date cum ar fi persoanele de contact, mesajele și fotografiile.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Datele cărora li s-a făcut backup nu se iau în considerare la calcularea cotei de stocare a contului Drive al copilului tău.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Poți dezactiva acest serviciu din Setări.<ph name="END_PARAGRAPH3" /></translation> @@ -4781,7 +4769,6 @@ <translation id="8368859634510605990">&Deschideți toate marcajele</translation> <translation id="8371695176452482769">Rostește acum</translation> <translation id="8372369524088641025">Cheie WEP greșită</translation> -<translation id="8373553483208508744">Dezactivează sunetul filelor</translation> <translation id="8378714024927312812">Gestionat de organizația ta</translation> <translation id="8379878387931047019">Dispozitivul nu acceptă tipul de cheie de securitate solicitată de acest site</translation> <translation id="8382913212082956454">Copiază adresa de &e-mail</translation> @@ -4889,7 +4876,6 @@ <translation id="8546930481464505581">Personalizează bara de atingere</translation> <translation id="8547013269961688403">Activează lupa de ecran complet</translation> <translation id="85486688517848470">Apasă lung pe tasta de căutare pentru a schimba comportamentul tastelor de pe rândul de sus</translation> -<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> @@ -4919,6 +4905,7 @@ <translation id="8598453409908276158">Pluginul în afara mediului de testare este blocat</translation> <translation id="8601206103050338563">Autentificare client TLS WWW</translation> <translation id="8602851771975208551">Un alt program de pe computerul dvs. a adăugat o aplicație care poate schimba modul în care funcționează Chrome.</translation> +<translation id="8604763363205185560">Ajută la îmbunătățirea Chrome și a securității acestuia</translation> <translation id="8605428685123651449">Memorie SQLite</translation> <translation id="8606726445206553943">Folosească dispozitive MIDI</translation> <translation id="8609465669617005112">Mutați mai sus</translation> @@ -5203,7 +5190,6 @@ <translation id="9038430547971207796">Data viitoare, telefonul tău va debloca dispozitivul <ph name="DEVICE_TYPE" />. Dezactivează Smart Lock din Setări.</translation> <translation id="9038649477754266430">Folosește un serviciu de predicții pentru a încărca paginile mai rapid</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Dezactivează sunetul filelor</translation> <translation id="9040661932550800571">Actualizezi parola pentru <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Accesul la fișierele de pe computer este dezactivat de administrator</translation> <translation id="9042893549633094279">Confidențialitate și securitate</translation> @@ -5301,7 +5287,6 @@ <translation id="920045321358709304">Caută pe <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Opțiuni de blocare a ecranului</translation> <translation id="9203398526606335860">&Analizare activată</translation> -<translation id="9203478404496196495">Activează sunetul filei</translation> <translation id="9203904171912129171">Selectează un dispozitiv</translation> <translation id="9203962528777363226">Administratorul acestui dispozitiv a dezactivat adăugarea de utilizatori noi</translation> <translation id="9213073329713032541">Instalarea a început.</translation>
diff --git a/chrome/app/resources/generated_resources_ru.xtb b/chrome/app/resources/generated_resources_ru.xtb index dc9afba..8b74676d 100644 --- a/chrome/app/resources/generated_resources_ru.xtb +++ b/chrome/app/resources/generated_resources_ru.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Чтобы отменить обновление, нажмите Esc (только для неофициальных версий).</translation> <translation id="1093457606523402488">Доступные сети:</translation> <translation id="1094607894174825014">Поступил запрос на чтение или запись с недействительным смещением на устройстве <ph name="DEVICE_NAME" />.</translation> -<translation id="109758035718544977">Включить звук на сайтах</translation> <translation id="1097658378307015415">Сначала войдите как гость, чтобы активировать работу сети <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Всегда переводить <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Остановить</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Не хотите, чтобы сохранялась история просмотров? Используйте режим инкогнито.</translation> <translation id="1213037489357051291">Отпечатков добавлено: <ph name="NUM_FINGERPRINTS" /></translation> <translation id="1215411991991485844">Добавлено фоновое приложение</translation> -<translation id="1216654534877302979">Отключить звук на сайтах</translation> <translation id="1216659994753476700">К сожалению, у нас нет доступа к вашему профилю. Файлы и данные на этом устройстве, скорее всего, были утеряны.<ph name="BR" /> <ph name="BR" /> Вам потребуется создать профиль заново.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Сохранение данных на вашем Google Диске</translation> <translation id="1288037062697528143">Ночной режим включится автоматически на закате</translation> <translation id="1288300545283011870">Настройки голоса</translation> -<translation id="1293177648337752319">Включить звук на сайте</translation> <translation id="1293264513303784526">Устройство USB-C (порт слева)</translation> <translation id="1293556467332435079">Файлы</translation> <translation id="1296497012903089238">Тип сертификата</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">В качестве главной страницы установлена страница быстрого доступа.</translation> <translation id="1436671784520050284">Продолжить настройку</translation> <translation id="1436784010935106834">Удалено</translation> -<translation id="1438632560381091872">Включить звук на вкладках</translation> <translation id="1442392616396121389">Префикс маршрутизации</translation> <translation id="144283815522798837">Выбрано: <ph name="NUMBER_OF_ITEMS_SELECTED" /></translation> <translation id="1444628761356461360">Этот аккаунт контролируется владельцем устройства (<ph name="OWNER_EMAIL" />)</translation> @@ -387,7 +383,6 @@ <translation id="1567387640189251553">После ввода пароля была подключена другая клавиатура. Это может быть попыткой узнать, какие клавиши вы нажимаете.</translation> <translation id="1567750922576943685">В целях защиты персональных данных вам необходимо подтвердить свою личность.</translation> <translation id="1567993339577891801">Консоль JavaScript</translation> -<translation id="1568067597247500137">Отключить звук на сайте</translation> <translation id="1568323446248056064">Открыть настройки экрана</translation> <translation id="1572266655485775982">Включить Wi-Fi</translation> <translation id="1572585716423026576">Установить как обои</translation> @@ -439,7 +434,6 @@ <translation id="1643072738649235303">Подпись ECDSA X9.62 с SHA-1</translation> <translation id="1644574205037202324">История</translation> <translation id="1645516838734033527">Чтобы защитить устройство <ph name="DEVICE_TYPE" /> с помощью Smart Lock, включите блокировку экрана на телефоне.</translation> -<translation id="1646102270785326155">После удаления пользователя все связанные с ним файлы и локальные данные также будут удалены. $1 сможет войти в аккаунт позже.</translation> <translation id="1646982517418478057">Введите пароль для шифрования этого сертификата</translation> <translation id="164814987133974965">Пользователь контролируемого аккаунта может посещать веб-страницы под вашим руководством. Как менеджер профиля в Chrome вы можете выполнять следующие операции: <ph name="BEGIN_BOLD" />разрешать или запрещать<ph name="END_BOLD" /> доступ к определенным сайтам; @@ -498,7 +492,6 @@ <translation id="1729533290416704613">Кроме того, расширение изменило поисковую систему, используемую по умолчанию при вводе запроса в омнибокс.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Чтобы удалить приложение, откройте "Настройки > Google Play > Управление настройками Android > Приложения (или Диспетчер приложений)" и найдите его в списке (возможно, потребуется пролистать экран вправо или влево). Выберите приложение и нажмите "Удалить" или "Отключить".<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Отправка запроса...</translation> -<translation id="1732215134274276513">Открепить вкладки</translation> <translation id="1733383495376208985">Выполнить шифрование синхронизированных данных, используя <ph name="BEGIN_LINK" />кодовую фразу<ph name="END_LINK" />. Шифрование не применяется к способам оплаты и адресам из Google Pay.</translation> <translation id="1734824808160898225">Возможно, <ph name="PRODUCT_NAME" /> не сможет обновляться автоматически.</translation> <translation id="1736419249208073774">Подробнее</translation> @@ -550,7 +543,6 @@ <translation id="1807938677607439181">Все файлы</translation> <translation id="1809734401532861917">Добавить мои закладки, историю, пароли и другие настройки в <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Предпросмотр недоступен</translation> -<translation id="1812631533912615985">Открепить вкладки</translation> <translation id="1813278315230285598">Службы</translation> <translation id="18139523105317219">Имя стороны EDI</translation> <translation id="1815083418640426271">Вставить как обычный текст</translation> @@ -709,7 +701,6 @@ <translation id="2065405795449409761">Браузером Chrome управляет автоматизированное тестовое ПО.</translation> <translation id="2070909990982335904">Названия, начинающиеся с точки, зарезервированы для системных файлов. Выберите другое название.</translation> <translation id="2071393345806050157">Нет локального файла журнала.</translation> -<translation id="2074527029802029717">Открепить вкладку</translation> <translation id="2075474481720804517">Батарея заряжена на <ph name="BATTERY_PERCENTAGE" />%</translation> <translation id="2075959085554270910">Позволяет включить/отключить функцию "Нажатие от прикосновения"</translation> <translation id="2076269580855484719">Скрыть подключаемый модуль</translation> @@ -1357,7 +1348,6 @@ <translation id="3045447014237878114">Этот сайт автоматически скачал несколько файлов</translation> <translation id="3046910703532196514">Веб-страница полностью</translation> <translation id="304747341537320566">Синтезаторы речи</translation> -<translation id="304826556400666995">Включить звук на вкладках</translation> <translation id="3053013834507634016">Использование ключа сертификата</translation> <translation id="3057861065630527966">Создать резервные копии фото и видео</translation> <translation id="3060379269883947824">Включить озвучивание при нажатии</translation> @@ -2343,7 +2333,6 @@ <translation id="4628762811416793313">Не удалось завершить настройку контейнера Linux. Повторите попытку.</translation> <translation id="4628948037717959914">Фото</translation> <translation id="4631887759990505102">Исполнитель</translation> -<translation id="4632483769545853758">Включить звук на вкладке</translation> <translation id="4633003931260532286">Для расширения требуется <ph name="IMPORT_NAME" /> версии не ранее <ph name="IMPORT_VERSION" />. Сейчас установлена версия <ph name="INSTALLED_VERSION" />.</translation> <translation id="4634771451598206121">Войти снова</translation> <translation id="4635398712689569051">Страница "<ph name="PAGE_NAME" />" недоступна в гостевом режиме</translation> @@ -2408,7 +2397,6 @@ <translation id="4736292055110123391">Синхронизировать закладки, пароли, историю и другие данные на всех ваших устройствах</translation> <translation id="4737715515457435632">Подключитесь к Интернету</translation> <translation id="473775607612524610">Обновить</translation> -<translation id="474217410105706308">Отключить звук на вкладке</translation> <translation id="4742746985488890273">Закрепить на панели запуска</translation> <translation id="4743260470722568160">Подробнее о том, <ph name="BEGIN_LINK" />как обновлять приложения<ph name="END_LINK" />…</translation> <translation id="4746351372139058112">Сообщения</translation> @@ -2633,7 +2621,6 @@ <translation id="5094721898978802975">Установка соединения со смежными нативными приложениями</translation> <translation id="5097002363526479830">Не удалось подключиться к сети <ph name="NAME" />: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Открыть все закладки</translation> -<translation id="5105855035535475848">Закрепить вкладки</translation> <translation id="5108967062857032718">Настройки – Удаление приложений для Android</translation> <translation id="5109044022078737958">Мия</translation> <translation id="5111692334209731439">Диспетчер закладок</translation> @@ -2698,7 +2685,6 @@ <translation id="520621735928254154">Ошибка при импорте сертификата</translation> <translation id="5209320130288484488">Устройства не найдены</translation> <translation id="5209518306177824490">Отпечаток SHA-1</translation> -<translation id="5210365745912300556">Закрыть вкладку</translation> <translation id="5213481667492808996">Служба передачи данных "<ph name="NAME" />" готова к работе.</translation> <translation id="5213891612754844763">Показать настройки прокси-сервера</translation> <translation id="521582610500777512">Фотография удалена.</translation> @@ -2750,7 +2736,6 @@ <translation id="5272654297705279635">Пользовательские настройки</translation> <translation id="5275352920323889391">Собака</translation> <translation id="5275973617553375938">Восстановленные файлы с Google Диска</translation> -<translation id="527605719918376753">Отключение звука на вкладке</translation> <translation id="527605982717517565">Всегда разрешать JavaScript для сайта <ph name="HOST" /></translation> <translation id="5280426389926346830">Создать ярлык?</translation> <translation id="528208740344463258">Чтобы скачивать и использовать приложения Android, необходимо установить это обязательное обновление. Во время установки пользоваться устройством <ph name="DEVICE_TYPE" /> нельзя. После обновления устройство <ph name="DEVICE_TYPE" /> перезагрузится автоматически.</translation> @@ -2873,7 +2858,6 @@ <translation id="5449551289610225147">Неправильный пароль</translation> <translation id="5449588825071916739">Добавить все вкладки в закладки</translation> <translation id="5449716055534515760">Закрыть &окно</translation> -<translation id="5453029940327926427">Закрыть вкладки</translation> <translation id="5454166040603940656">с помощью <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Недопустимые данные</translation> <translation id="5457459357461771897">Доступ к фотографиям, музыке и другим медиафайлам на вашем компьютере, а также их удаление</translation> @@ -3338,7 +3322,6 @@ <translation id="6122875415561139701">Запись данных на устройстве <ph name="DEVICE_NAME" /> запрещена.</translation> <translation id="6124650939968185064">От этих расширений зависят следующие:</translation> <translation id="6125479973208104919">Необходимо заново добавить аккаунт на <ph name="DEVICE_TYPE" />.</translation> -<translation id="612596694132302162">Включить звук на сайте</translation> <translation id="6129691635767514872">Выбранные данные удалены из Chrome и с синхронизированных устройств. История также может храниться в вашем аккаунте Google, например в виде поисковых запросов и сведений из сервисов Google. Их можно найти на сайте <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Комментарий к сертификату Netscape</translation> <translation id="6129953537138746214">Пробел</translation> @@ -3541,7 +3524,6 @@ <translation id="6436164536244065364">Просмотреть в Интернет-магазине</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" />: воспроизводится аудио</translation> <translation id="6442187272350399447">Супер</translation> -<translation id="6442697326824312960">Открепить вкладку</translation> <translation id="6444070574980481588">Установите дату и время</translation> <translation id="6445450263907939268">Вы можете восстановить прежние настройки.</translation> <translation id="6447842834002726250">Файлы сookie</translation> @@ -3744,7 +3726,6 @@ <translation id="6770664076092644100">Подтвердить через NFC</translation> <translation id="6771503742377376720">Является центром сертификации</translation> <translation id="6777817260680419853">Попытка переадресации заблокирована</translation> -<translation id="6778959797435875428">Включить звук на сайтах</translation> <translation id="677965093459947883">Очень мелкий</translation> <translation id="6780439250949340171">управление другими настройками</translation> <translation id="6781284683813954823">Ссылка на дудл</translation> @@ -4061,7 +4042,6 @@ <translation id="7257666756905341374">Доступ к копируемым и вставляемым данным</translation> <translation id="7258697411818564379">PIN-код сохранен</translation> <translation id="7262004276116528033">Сервис входа размещен в домене <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Закрыть вкладки</translation> <translation id="7268659760406822741">Доступные сервисы</translation> <translation id="7270858098575133036">Уведомлять меня о сайтах, пытающихся использовать системные сообщения для доступа к MIDI-устройствам</translation> <translation id="7272674038937250585">Описания нет</translation> @@ -4251,7 +4231,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">Разобрать по копиям</translation> <translation id="7576976045740938453">Возникла проблема с демонстрационным режимом аккаунта.</translation> -<translation id="7579149537961810247">Отключить звук на сайтах</translation> <translation id="7580671184200851182">Воспроизводить одно и то же аудио через все динамики (моноаудио)</translation> <translation id="7581462281756524039">Инструмент очистки</translation> <translation id="7582582252461552277">Предпочитать эту сеть</translation> @@ -4605,7 +4584,6 @@ <translation id="8068253693380742035">Нажмите, чтобы войти</translation> <translation id="8069615408251337349">Виртуальный принтер Google</translation> <translation id="8071432093239591881">Печатать как изображение</translation> -<translation id="8072988827236813198">Закрепить вкладки</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Данные приложений – это любая информация, которую приложения сохраняют в соответствии с настройками разработчика. Она может включать контакты, сообщения, фотографии и многое другое.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Данные резервных копий не занимают место в хранилище Google Диска.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Вы можете отключить эту функцию в настройках.<ph name="END_PARAGRAPH3" /></translation> @@ -4790,7 +4768,6 @@ <translation id="8368859634510605990">&Открыть все закладки</translation> <translation id="8371695176452482769">Говорите</translation> <translation id="8372369524088641025">Недопустимый ключ WEP</translation> -<translation id="8373553483208508744">Отключить звук на вкладках</translation> <translation id="8378714024927312812">Управляется вашей организацией</translation> <translation id="8379878387931047019">Устройство не поддерживает тип электронного ключа, запрашиваемый этим сайтом.</translation> <translation id="8382913212082956454">Копировать &адрес электронной почты</translation> @@ -4898,7 +4875,6 @@ <translation id="8546930481464505581">Настроить Touch Bar</translation> <translation id="8547013269961688403">Включить полноэкранную лупу</translation> <translation id="85486688517848470">Чтобы сменить режим клавиш верхнего ряда, удерживайте кнопку поиска</translation> -<translation id="855081842937141170">Закрепить вкладку</translation> <translation id="8551388862522347954">Лицензии</translation> <translation id="8553342806078037065">Другие пользователи</translation> <translation id="8554899698005018844">Язык не указан</translation> @@ -5213,7 +5189,6 @@ <translation id="9038430547971207796">Теперь вы можете снимать блокировку устройства <ph name="DEVICE_TYPE" /> с помощью телефона. Чтобы выключить Smart Lock, перейдите в настройки.</translation> <translation id="9038649477754266430">Использовать подсказки для ускорения загрузки страниц</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Отключить звук на вкладках</translation> <translation id="9040661932550800571">Обновить пароль для <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Доступ к локальным файлам на вашем компьютере отключен администратором.</translation> <translation id="9042893549633094279">Конфиденциальность и безопасность</translation> @@ -5311,7 +5286,6 @@ <translation id="920045321358709304">Искать в <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Параметры блокировки экрана</translation> <translation id="9203398526606335860">&Сбор данных включен</translation> -<translation id="9203478404496196495">Включение звука на вкладке</translation> <translation id="9203904171912129171">Выберите устройство</translation> <translation id="9203962528777363226">Администратор этого устройства отключил возможность добавлять новых пользователей</translation> <translation id="9213073329713032541">Установка началась.</translation>
diff --git a/chrome/app/resources/generated_resources_sk.xtb b/chrome/app/resources/generated_resources_sk.xtb index dc26bf75..9b861ed6 100644 --- a/chrome/app/resources/generated_resources_sk.xtb +++ b/chrome/app/resources/generated_resources_sk.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Ak chcete preskočiť aktualizáciu, stlačte kláves Escape (len pre neoficiálne zostavy).</translation> <translation id="1093457606523402488">Viditeľné siete:</translation> <translation id="1094607894174825014">Na zariadení <ph name="DEVICE_NAME" /> bola vyžiadaná operácia čítania alebo zápisu s nesprávnym odsadením.</translation> -<translation id="109758035718544977">Zapnúť zvuk webov</translation> <translation id="1097658378307015415">Ak chcete aktivovať sieť <ph name="NETWORK_ID" />, vstúpte pred prihlásením ako hosť</translation> <translation id="1103523840287552314">Vždy preložiť nasledujúci jazyk: <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Zastaviť</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Používajte web bez ukladania histórie prehliadania v okne inkognito</translation> <translation id="1213037489357051291">Počet nastavených odtlačkov: <ph name="NUM_FINGERPRINTS" /></translation> <translation id="1215411991991485844">Bola pridaná nová aplikácia na pozadí</translation> -<translation id="1216654534877302979">Vypnúť zvuk webov</translation> <translation id="1216659994753476700">Je nám to ľúto, ale nemôžeme získať prístup k vášmu profilu. Súbory a dáta uložené na tomto zariadení môžu byť stratené.<ph name="BR" /> <ph name="BR" /> Svoj profil si musíte znova založiť.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Ukladať údaje v účte na Disku Google</translation> <translation id="1288037062697528143">Nočný režim sa automaticky zapne pri západe slnka</translation> <translation id="1288300545283011870">Vlastnosti hlasovej odozvy</translation> -<translation id="1293177648337752319">Zapnúť zvuk webu</translation> <translation id="1293264513303784526">Zariadenie USB-C (port vľavo)</translation> <translation id="1293556467332435079">Súbory</translation> <translation id="1296497012903089238">Typ certifikátu</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Domovská stránka je stránka na novej karte</translation> <translation id="1436671784520050284">Pokračovať v nastavení</translation> <translation id="1436784010935106834">Odstránené</translation> -<translation id="1438632560381091872">Obnoviť zvuk kariet</translation> <translation id="1442392616396121389">Predpona smerovania</translation> <translation id="144283815522798837">Počet vybratých položiek: <ph name="NUMBER_OF_ITEMS_SELECTED" /></translation> <translation id="1444628761356461360">Toto nastavenie spravuje vlastník zariadenia <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Od posledného zadania hesla bola pripojená iná klávesnica. Je možné, že sa pokúša ukradnúť vaše stlačenia klávesov.</translation> <translation id="1567750922576943685">Overenie totožnosti pomáha chrániť vaše osobné informácie</translation> <translation id="1567993339577891801">Konzola JavaScript</translation> -<translation id="1568067597247500137">Vypnúť zvuk webu</translation> <translation id="1568323446248056064">Otvoriť nastavenia obrazovky</translation> <translation id="1572266655485775982">Povolenie Wi‑Fi</translation> <translation id="1572585716423026576">Nastaviť ako tapetu</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">Podpis X9.62 ECDSA s SHA-1</translation> <translation id="1644574205037202324">História</translation> <translation id="1645516838734033527">V rámci zabezpečenia vášho zariadenia <ph name="DEVICE_TYPE" /> funkcia Smart Lock vyžaduje, aby bola v telefóne nastavená zámka obrazovky.</translation> -<translation id="1646102270785326155">Všetky súbory a miestne údaje priradené k tomuto používateľovi budú po jeho odstránení natrvalo vymazané. $1 sa môže neskôr stále prihlásiť.</translation> <translation id="1646982517418478057">Zadajte heslo na zašifrovanie tohto certifikátu</translation> <translation id="164814987133974965">Kontrolovaný používateľ môže preskúmavať web pod vaším vedením. Ako správca kontrolovaného používateľa môžete <ph name="BEGIN_BOLD" />povoliť alebo zakázať<ph name="END_BOLD" /> určité webové stránky, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Tiež určuje, ktorá stránka sa zobrazí pri vyhľadávaní pomocou všeobecného poľa.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Ak chcete odstrániť aplikácie, prejdite do časti Nastavenia > Obchod Google Play > Spravovať predvoľby Androidu > Aplikácie alebo Správca aplikácií. Potom klepnite na aplikáciu, ktorú chcete odinštalovať (možno budete musieť aplikáciu nájsť potiahnutím prstom doľava alebo doprava). Potom klepnite na možnosť Odinštalovať alebo Deaktivovať.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Posielanie požiadavky...</translation> -<translation id="1732215134274276513">Odopnúť karty</translation> <translation id="1733383495376208985">Šifrovať synchronizované údaje pomocou vlastnej <ph name="BEGIN_LINK" />prístupovej frázy synchronizácie<ph name="END_LINK" />. Nezahŕňa to spôsoby platby ani adresy zo služby Google Pay.</translation> <translation id="1734824808160898225">Prehliadač <ph name="PRODUCT_NAME" /> sa sám nemusí pravidelne aktualizovať</translation> <translation id="1736419249208073774">Preskúmať</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Všetky súbory</translation> <translation id="1809734401532861917">Pridať záložky, históriu, heslá a ďalšie nastavenia do účtu <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Ukážka nie je k dispozícii</translation> -<translation id="1812631533912615985">Odopnúť karty</translation> <translation id="1813278315230285598">Služby</translation> <translation id="18139523105317219">Názov strany EDI</translation> <translation id="1815083418640426271">Prilepiť ako čistý text</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chrome je ovládaný automatizovaným testovacím softvérom.</translation> <translation id="2070909990982335904">Názvy začínajúce bodkou sú vyhradené pre systém. Vyberte iný názov.</translation> <translation id="2071393345806050157">Žiadny miestny súbor denníka nie je k dispozícii.</translation> -<translation id="2074527029802029717">Odopnúť kartu</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" /> % batérie</translation> <translation id="2075959085554270910">Umožňuje povoliť alebo zakázať kliknutie klepnutím a presunutie klepnutím</translation> <translation id="2076269580855484719">Skryť tento doplnok</translation> @@ -1355,7 +1346,6 @@ <translation id="3045447014237878114">Tento web automaticky stiahol viacero súborov</translation> <translation id="3046910703532196514">Webová stránka, Úplné</translation> <translation id="304747341537320566">Nástroje hlasovej odozvy</translation> -<translation id="304826556400666995">Obnoviť zvuk kariet</translation> <translation id="3053013834507634016">Použitie kľúča certifikátu</translation> <translation id="3057861065630527966">Zálohovať fotky a videá</translation> <translation id="3060379269883947824">Povoliť počúvanie vybraného textu</translation> @@ -2341,7 +2331,6 @@ <translation id="4628762811416793313">Nastavenie kontajnera Linux sa nedokončilo. Skúste to znova.</translation> <translation id="4628948037717959914">Fotografia</translation> <translation id="4631887759990505102">Interpret</translation> -<translation id="4632483769545853758">Obnoviť zvuk karty</translation> <translation id="4633003931260532286">Rozšírenie vyžaduje <ph name="IMPORT_NAME" /> minimálne vo verzii <ph name="IMPORT_VERSION" />, ale nainštalovaná je iba verzia <ph name="INSTALLED_VERSION" /></translation> <translation id="4634771451598206121">Znova prihlásiť...</translation> <translation id="4635398712689569051">Stránka <ph name="PAGE_NAME" /> nie je k dispozícii pre hostí.</translation> @@ -2406,7 +2395,6 @@ <translation id="4736292055110123391">Synchronizujte svoje záložky, heslá, históriu a ďalší obsah vo všetkých zariadeniach</translation> <translation id="4737715515457435632">Pripojte sa k sieti</translation> <translation id="473775607612524610">Aktualizovať</translation> -<translation id="474217410105706308">Stlmiť kartu</translation> <translation id="4742746985488890273">Pripnúť na poličku</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Ako aktualizovať aplikácie<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Správy</translation> @@ -2631,7 +2619,6 @@ <translation id="5094721898978802975">Komunikovať so spolupracujúcimi natívnymi aplikáciami</translation> <translation id="5097002363526479830">K sieti „<ph name="NAME" />“ sa nepodarilo pripojiť: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Otvoriť všetky záložky</translation> -<translation id="5105855035535475848">Pripnutie kariet</translation> <translation id="5108967062857032718">Nastavenia – odstránenie aplikácií pre Android</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">&Správca záložiek</translation> @@ -2696,7 +2683,6 @@ <translation id="520621735928254154">Chyba importovania certifikátu</translation> <translation id="5209320130288484488">Nenašli sa žiadne zariadenia</translation> <translation id="5209518306177824490">Odtlačok SHA-1</translation> -<translation id="5210365745912300556">Zatvoriť kartu</translation> <translation id="5213481667492808996">Dátová služba <ph name="NAME" /> je pripravená na použitie</translation> <translation id="5213891612754844763">Zobraziť nastavenia proxy servera</translation> <translation id="521582610500777512">Fotka bola zahodená</translation> @@ -2748,7 +2734,6 @@ <translation id="5272654297705279635">Vlastné nastavenia</translation> <translation id="5275352920323889391">Pes</translation> <translation id="5275973617553375938">Obnovené súbory z Disku Google</translation> -<translation id="527605719918376753">Stlmiť kartu</translation> <translation id="527605982717517565">Vždy povoliť jazyk JavaScript na stránkach <ph name="HOST" /></translation> <translation id="5280426389926346830">Vytvoriť odkaz?</translation> <translation id="528208740344463258">Ak chcete stiahnuť a používať aplikácie pre Android, najprv musíte nainštalovať požadovanú aktualizáciu. Počas aktualizácie nemôžete <ph name="DEVICE_TYPE" /> používať. Po jej dokončení sa <ph name="DEVICE_TYPE" /> reštartuje.</translation> @@ -2871,7 +2856,6 @@ <translation id="5449551289610225147">Neplatné heslo</translation> <translation id="5449588825071916739">Všetky karty uložiť ako záložky</translation> <translation id="5449716055534515760">Zavrieť o&kno</translation> -<translation id="5453029940327926427">Zavrieť karty</translation> <translation id="5454166040603940656">s poskytovateľom <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Neplatné</translation> <translation id="5457459357461771897">Čítať a odstraňovať fotky, hudbu a ďalšie médiá z tohto počítača</translation> @@ -3336,7 +3320,6 @@ <translation id="6122875415561139701">Operácia zápisu je na zariadení <ph name="DEVICE_NAME" /> zakázaná.</translation> <translation id="6124650939968185064">Od tohto rozšírenia závisia nasledujúce rozšírenia:</translation> <translation id="6125479973208104919">Do tohto zariadenia <ph name="DEVICE_TYPE" /> si žiaľ budete musieť znova pridať účet.</translation> -<translation id="612596694132302162">Zapnúť zvuk webu</translation> <translation id="6129691635767514872">Vybrané dáta boli odstránené z Chromu a synchronizovaných zariadení. Váš účet Google môže mať ďalšie formy histórie prehliadania na adrese <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> (napríklad vyhľadávania a aktivity v iných službách Googlu).</translation> <translation id="6129938384427316298">Netscape – komentár certifikátu</translation> <translation id="6129953537138746214">Medzera</translation> @@ -3539,7 +3522,6 @@ <translation id="6436164536244065364">Zobraziť v Internetovom obchode</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – Prehráva sa zvuk</translation> <translation id="6442187272350399447">Skvelý</translation> -<translation id="6442697326824312960">Odopnúť kartu</translation> <translation id="6444070574980481588">Nastavenie dátumu a času</translation> <translation id="6445450263907939268">Ak ste tieto zmeny nechceli, môžete obnoviť predchádzajúce nastavenia.</translation> <translation id="6447842834002726250">Súbory cookie</translation> @@ -3742,7 +3724,6 @@ <translation id="6770664076092644100">Overiť prostredníctvom NFC</translation> <translation id="6771503742377376720">Je certifikačnou autoritou</translation> <translation id="6777817260680419853">Presmerovanie bolo zablokované</translation> -<translation id="6778959797435875428">Zapnúť zvuk webov</translation> <translation id="677965093459947883">Veľmi malé</translation> <translation id="6780439250949340171">spravovať ďalšie nastavenia</translation> <translation id="6781284683813954823">Odkaz na doodle</translation> @@ -4059,7 +4040,6 @@ <translation id="7257666756905341374">Čítať údaje, ktoré kopírujete a prilepujete</translation> <translation id="7258697411818564379">Váš kód PIN bol pridaný</translation> <translation id="7262004276116528033">Túto prihlasovaciu službu hostí doména <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Zavrieť karty</translation> <translation id="7268659760406822741">Dostupné služby</translation> <translation id="7270858098575133036">Opýtať sa, keď bude chcieť web použiť na prístup k zariadeniam MIDI správy exkluzívne pre systém</translation> <translation id="7272674038937250585">Popis nie je k dispozícii</translation> @@ -4249,7 +4229,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">Kompletovať</translation> <translation id="7576976045740938453">Vyskytol sa problém s účtom režimu ukážky.</translation> -<translation id="7579149537961810247">Vypnúť zvuk webov</translation> <translation id="7580671184200851182">Prehrávajte rovnaký zvuk zo všetkých reproduktorov (monofónny zvuk)</translation> <translation id="7581462281756524039">Nástroj na čistenie</translation> <translation id="7582582252461552277">Preferovať túto sieť</translation> @@ -4603,7 +4582,6 @@ <translation id="8068253693380742035">Dotykom sa prihlásite</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Vytlačiť ako obrázok</translation> -<translation id="8072988827236813198">Pripnúť karty</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Dáta aplikácií môžu byť ľubovoľné dáta, ktoré aplikácie uložili (v závislosti od nastavení vývojára), vrátane potenciálne citlivých informácií, ako sú kontakty, správy a fotky.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Zálohované dáta sa nezapočítavajú do kvóty úložiska Disku.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Túto službu môžete vypnúť v Nastaveniach.<ph name="END_PARAGRAPH3" /></translation> @@ -4788,7 +4766,6 @@ <translation id="8368859634510605990">&Otvoriť všetky záložky</translation> <translation id="8371695176452482769">Hovorte…</translation> <translation id="8372369524088641025">Zlý kľúč WEP</translation> -<translation id="8373553483208508744">Stlmiť karty</translation> <translation id="8378714024927312812">Spravované vašou organizáciou</translation> <translation id="8379878387931047019">Toto zariadenie nepodporuje typ bezpečnostného kľúča požadovaného týmto webom</translation> <translation id="8382913212082956454">Kopírovať &e-mailovú adresu</translation> @@ -4896,7 +4873,6 @@ <translation id="8546930481464505581">Prispôsobiť ovládač Touch Bar</translation> <translation id="8547013269961688403">Zapnúť lupu celej obrazovky</translation> <translation id="85486688517848470">Podržaním klávesa vyhľadávania prepnete správanie klávesov v hornom riadku</translation> -<translation id="855081842937141170">Pripnúť kartu</translation> <translation id="8551388862522347954">Licencie</translation> <translation id="8553342806078037065">Spravovať ďalšie osoby</translation> <translation id="8554899698005018844">Žiadny jazyk</translation> @@ -5211,7 +5187,6 @@ <translation id="9038430547971207796">Zariadenie <ph name="DEVICE_TYPE" /> nabudúce odomknete telefónom. Smart Lock môžete vypnúť v Nastaveniach.</translation> <translation id="9038649477754266430">Používať službu predpovedí na rýchlejšie načítanie stránok</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Stlmiť karty</translation> <translation id="9040661932550800571">Aktualizovať heslo pre adresu <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Prístup k miestnym súborom vo vašom počítači zakázal správca</translation> <translation id="9042893549633094279">Ochrana súkromia a zabezpečenie</translation> @@ -5309,7 +5284,6 @@ <translation id="920045321358709304">Hľadať vyhľadávačom <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Možnosti zámky obrazovky</translation> <translation id="9203398526606335860">&Profilovanie povolené</translation> -<translation id="9203478404496196495">Obnoviť zvuk karty</translation> <translation id="9203904171912129171">Výber zariadenia</translation> <translation id="9203962528777363226">Správca tohto zariadenia zakázal pridávanie nových používateľov</translation> <translation id="9213073329713032541">Inštalácia bola úspešne spustená.</translation>
diff --git a/chrome/app/resources/generated_resources_sl.xtb b/chrome/app/resources/generated_resources_sl.xtb index a557160..4a52345 100644 --- a/chrome/app/resources/generated_resources_sl.xtb +++ b/chrome/app/resources/generated_resources_sl.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Pritisnite Esc, če želite preskočiti (samo neuradne delovne različice).</translation> <translation id="1093457606523402488">Vidna omrežja:</translation> <translation id="1094607894174825014">Dejanje branja ali pisanja je bilo zahtevano z neveljavnim zamikom v tej napravi: »<ph name="DEVICE_NAME" />«.</translation> -<translation id="109758035718544977">Vklopi zvok spletnih mest</translation> <translation id="1097658378307015415">Pred prijavo vstopite kot gost, da aktivirate omrežje <ph name="NETWORK_ID" />.</translation> <translation id="1103523840287552314">Vedno prevedi ta jezik: <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Ustavi</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Uporabljajte splet brez shranjevanja zgodovine brskanja z oknom brez beleženja zgodovine</translation> <translation id="1213037489357051291">Št. nastavljenih prstnih odtisov: <ph name="NUM_FINGERPRINTS" /></translation> <translation id="1215411991991485844">Dodan je nov program, ki se izvaja v ozadju</translation> -<translation id="1216654534877302979">Izklopi zvok spletnih mest</translation> <translation id="1216659994753476700">Ne moremo dostopati do vašega profila. Datoteke in podatki, shranjeni v tej napravi, so morda izgubljeni.<ph name="BR" /> <ph name="BR" /> Profile boste morali znova nastaviti.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Shranjevanje podatkov v računu za Google Drive</translation> <translation id="1288037062697528143">Nočna svetloba se bo samodejno vklopila ob sončnem zahodu.</translation> <translation id="1288300545283011870">Lastnosti govora</translation> -<translation id="1293177648337752319">Vklopi zvok spletnega mesta</translation> <translation id="1293264513303784526">Naprava USB-C (leva vrata)</translation> <translation id="1293556467332435079">Datoteke</translation> <translation id="1296497012903089238">Vrsta potrdila</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Domača stran je nov zavihek s povezavami</translation> <translation id="1436671784520050284">Nadaljuj nastavitev</translation> <translation id="1436784010935106834">Odstranjeno</translation> -<translation id="1438632560381091872">Vklop zvoka zavihkov</translation> <translation id="1442392616396121389">Predpona za usmerjanje</translation> <translation id="144283815522798837">Št. izbranih: <ph name="NUMBER_OF_ITEMS_SELECTED" /></translation> <translation id="1444628761356461360">To nastavitev upravlja lastnik naprave <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Od zadnjega vnosa gesla je bila priklopljena druga tipkovnica, ki morda poskuša beležiti vse, kar natipkate.</translation> <translation id="1567750922576943685">Če preverite identiteto, bodo vaši osebni podatki varnejši</translation> <translation id="1567993339577891801">Konzola JavaScript</translation> -<translation id="1568067597247500137">Izklopi zvok spletnega mesta</translation> <translation id="1568323446248056064">Odpiranje nastavitev zaslona v napravi</translation> <translation id="1572266655485775982">Omogočanje Wi-Fi-ja</translation> <translation id="1572585716423026576">Nastavi kot ozadje</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">Podpis X9.62 ECDSA z algoritmom SHA-1</translation> <translation id="1644574205037202324">Zgodovina</translation> <translation id="1645516838734033527">Zaradi varnosti naprave <ph name="DEVICE_TYPE" /> zahteva funkcija Smart Lock v telefonu zaklepanje zaslona.</translation> -<translation id="1646102270785326155">Vse datoteke in lokalni podatki, povezani s tem uporabnikom, bodo trajno izbrisani, ko odstranite uporabnika. $1 se lahko pozneje še vedno prijavi.</translation> <translation id="1646982517418478057">Vnesite geslo za šifriranje tega potrdila</translation> <translation id="164814987133974965">Zaščiteni uporabnik lahko raziskuje splet tako, da ga pri tem vodite vi. Kot upravitelj zaščitenega uporabnika imate te možnosti: <ph name="BEGIN_BOLD" />omogočanje ali prepoved dostopa do<ph name="END_BOLD" /> nekaterih spletnih mest, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Določa tudi, katera stran je prikazana, ko iščete v naslovni vrstici.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Če želite odstraniti aplikacije, pojdite v »Nastavitve« > »Trgovina Google Play« > »Upravljanje nastavitev Androida« > »Aplikacije« ali odprite upravitelja aplikacij. Nato se dotaknite aplikacije, ki jo želite odstraniti (morda boste morali s prstom povleči v desno ali levo, da jo boste našli). Nato se dotaknite »Odstrani« ali »Onemogoči«.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Pošiljanje zahteve ...</translation> -<translation id="1732215134274276513">Odpni zavihke</translation> <translation id="1733383495376208985">Šifriranje sinhroniziranih podatkov z vašim <ph name="BEGIN_LINK" />geslom za sinhronizacijo<ph name="END_LINK" />. To ne vključuje plačilnih sredstev in naslovov iz Googla Pay.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> se morda ne bo mogel posodabljati</translation> <translation id="1736419249208073774">Razišči</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Vse datoteke</translation> <translation id="1809734401532861917">Dodaj moje zaznamke, zgodovino, gesla in druge nastavitve v profil <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Predogled ni na voljo</translation> -<translation id="1812631533912615985">Odpni zavihke</translation> <translation id="1813278315230285598">Storitve</translation> <translation id="18139523105317219">Ime skupine EDI</translation> <translation id="1815083418640426271">Prilepi kot navadno besedilo</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chrome upravlja avtomatizirana preskusna programska oprema.</translation> <translation id="2070909990982335904">Imena, ki se začnejo s piko, so rezervirana za sistem. Izberite drugo ime.</translation> <translation id="2071393345806050157">Ni lokalne dnevniške datoteke.</translation> -<translation id="2074527029802029717">Odpni zavihek</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" /> % energije akumulatorja</translation> <translation id="2075959085554270910">Omogoča, da omogočite/onemogočite funkciji »dotaknite se za klik« in »vlečenje z dotikom«</translation> <translation id="2076269580855484719">Skrij vtičnik</translation> @@ -1352,7 +1343,6 @@ <translation id="3045447014237878114">To spletno mesto je samodejno preneslo več datotek</translation> <translation id="3046910703532196514">Spletna stran, dokončano</translation> <translation id="304747341537320566">Mehanizmi za govor</translation> -<translation id="304826556400666995">Vklop zvoka zavihkov</translation> <translation id="3053013834507634016">Raba ključa potrdila</translation> <translation id="3057861065630527966">Varnostno kopiranje fotografij videoposnetkov</translation> <translation id="3060379269883947824">Omogoči storitev Izberite in poslušajte</translation> @@ -1998,7 +1988,7 @@ <translation id="4037084878352560732">Konj</translation> <translation id="4037889604535939429">Urejanje osebe</translation> <translation id="4042264909745389898">Pogoji za Googlov OS Chrome</translation> -<translation id="4042863763121826131">{NUM_PAGES,plural, =1{Izhodna stran}one{Izhodne strani}two{Izhodne strani}few{Izhodne strani}other{Izhodne strani}}</translation> +<translation id="4042863763121826131">{NUM_PAGES,plural, =1{Zapri stran}one{Zapri strani}two{Zapri strani}few{Zapri strani}other{Zapri strani}}</translation> <translation id="4044612648082411741">Vnesite geslo za potrdilo</translation> <translation id="404493185430269859">Privzeti iskalnik</translation> <translation id="4052120076834320548">Drobna</translation> @@ -2335,7 +2325,6 @@ <translation id="4628762811416793313">Nastavitev vsebnika za Linux se ni dokončala. Poskusite znova.</translation> <translation id="4628948037717959914">Fotografija</translation> <translation id="4631887759990505102">Izvajalec</translation> -<translation id="4632483769545853758">Vklop zvoka zavihka</translation> <translation id="4633003931260532286">Razširitev zahteva »<ph name="IMPORT_NAME" />« z najmanjšo številko različice »<ph name="IMPORT_VERSION" />«, vendar je nameščena samo različica »<ph name="INSTALLED_VERSION" />«</translation> <translation id="4634771451598206121">Prijavite se znova ...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> ni na voljo gostom.</translation> @@ -2399,7 +2388,6 @@ <translation id="4735803855089279419">Sistemu ni uspelo določiti identifikatorjev naprave za to napravo.</translation> <translation id="4737715515457435632">Povežite se z omrežjem</translation> <translation id="473775607612524610">Posodobi</translation> -<translation id="474217410105706308">Izklop zvoka zavihka</translation> <translation id="4742746985488890273">Pripni na polico</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Preberite, kako posodobite aplikacije<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Sporočila</translation> @@ -2624,7 +2612,6 @@ <translation id="5094721898978802975">Komuniciranje s sodelujočimi izvornimi aplikacijami</translation> <translation id="5097002363526479830">Povezava z omrežjem »<ph name="NAME" />« ni uspela: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Odpri vse zaznamke</translation> -<translation id="5105855035535475848">Pripni zavihke</translation> <translation id="5108967062857032718">Nastavitve – odstranitev aplikacij za Android</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">&Upravitelj zaznamkov</translation> @@ -2689,7 +2676,6 @@ <translation id="520621735928254154">Napaka pri uvozu potrdila</translation> <translation id="5209320130288484488">Najti ni mogoče nobene naprave</translation> <translation id="5209518306177824490">SHA-1 Fingerprint</translation> -<translation id="5210365745912300556">Zapri zavihek</translation> <translation id="5213481667492808996">Podatkovno storitev omrežja »<ph name="NAME" />« lahko začnete uporabljati</translation> <translation id="5213891612754844763">Prikaži nastavitve strežnika proxy</translation> <translation id="521582610500777512">Fotografija je bila zavržena</translation> @@ -2740,7 +2726,6 @@ <translation id="5270167208902136840">Prikaži še toliko aplikacij: <ph name="NUMBER_OF_MORE_APPS" /></translation> <translation id="5275352920323889391">Pes</translation> <translation id="5275973617553375938">Obnovljene datoteke iz Googla Drive</translation> -<translation id="527605719918376753">Izklop zvoka zavihka</translation> <translation id="527605982717517565">Vedno dovoli JavaScript na mestu <ph name="HOST" /></translation> <translation id="5280426389926346830">Želite ustvariti bližnjico?</translation> <translation id="528208740344463258">Če želite prenesti in uporabljati aplikacije za Android, morate najprej namestiti to zahtevano posodobitev. Med posodabljanjem naprave <ph name="DEVICE_TYPE" /> ne morete uporabljati. Po dokončani namestitvi se bo naprava <ph name="DEVICE_TYPE" /> znova zagnala.</translation> @@ -2863,7 +2848,6 @@ <translation id="5449551289610225147">Neveljavno geslo</translation> <translation id="5449588825071916739">Dodaj vse zavihke med zaznamke</translation> <translation id="5449716055534515760">Zapri &okno</translation> -<translation id="5453029940327926427">Zapri zavihke</translation> <translation id="5454166040603940656">pri ponudniku <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Neveljavno</translation> <translation id="5457459357461771897">Branje in izbris fotografij, glasbe in drugih predstavnosti v računalniku</translation> @@ -3330,7 +3314,6 @@ <translation id="6122875415561139701">V tej napravi ni dovoljeno dejanje pisanja: »<ph name="DEVICE_NAME" />«.</translation> <translation id="6124650939968185064">Od te razširitve so odvisne naslednje razširitve:</translation> <translation id="6125479973208104919">V napravi <ph name="DEVICE_TYPE" /> boste morali znova dodati račun.</translation> -<translation id="612596694132302162">Vklopi zvok spletnega mesta</translation> <translation id="6129691635767514872">Izbrani podatki so bili odstranjeni iz Chroma in sinhroniziranih naprav. V Google Računu so morda druge vrste zgodovine brskanja, kot so iskanja in dejavnosti iz drugih Googlovih storitev, na <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Pripomba o Netscapeovem potrdilu</translation> <translation id="6129953537138746214">Presledek</translation> @@ -3533,7 +3516,6 @@ <translation id="6436164536244065364">Ogled v spletni trgovini</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – zvok se predvaja</translation> <translation id="6442187272350399447">Navdušenec</translation> -<translation id="6442697326824312960">Odpni zavihek</translation> <translation id="6444070574980481588">Nastavitev datuma in časa</translation> <translation id="6445450263907939268">Če niste želeli teh sprememb, lahko obnovite prejšnje nastavitve.</translation> <translation id="6447842834002726250">Piškotki</translation> @@ -3736,7 +3718,6 @@ <translation id="6770664076092644100">Preverite prek NFC-ja</translation> <translation id="6771503742377376720">Je overitelj potrdil</translation> <translation id="6777817260680419853">Preusmeritev je blokirana</translation> -<translation id="6778959797435875428">Vklopi zvok spletnih mest</translation> <translation id="677965093459947883">Zelo majhna</translation> <translation id="6780439250949340171">upravljanje drugih nastavitev</translation> <translation id="6781284683813954823">Povezava do priložnostnega logotipa</translation> @@ -4013,7 +3994,7 @@ <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="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="720715819012336933">{NUM_PAGES,plural, =1{Zapri stran}one{Zapri strani}two{Zapri strani}few{Zapri strani}other{Zapri strani}}</translation> <translation id="7210499381659830293">Tiskalniki razširitev</translation> <translation id="721467499098558573">Pritisnite in vsaj 5 sekund pridržite gumb na varnostnem ključu</translation> <translation id="7216409898977639127">Ponudnik mobilnih storitev</translation> @@ -4053,7 +4034,6 @@ <translation id="7257666756905341374">Branje podatkov, ki jih kopirate in prilepite</translation> <translation id="7258697411818564379">Vaša koda PIN je dodana</translation> <translation id="7262004276116528033">Prijavno storitev gosti <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Zapri zavihke</translation> <translation id="7268659760406822741">Razpoložljive storitve</translation> <translation id="7270858098575133036">Vprašaj, ko želi spletno mesto uporabiti sporočila sysex za dostop do naprav MIDI</translation> <translation id="7272674038937250585">Ni opisa</translation> @@ -4243,7 +4223,6 @@ <translation id="7576032389798113292">6 x 4</translation> <translation id="7576690715254076113">Zbiranje kopij</translation> <translation id="7576976045740938453">Prišlo je težave z računom predstavitvenega računa.</translation> -<translation id="7579149537961810247">Izklopi zvok spletnih mest</translation> <translation id="7580671184200851182">Predvajaj isti zvok prek vseh zvočnikov (mono zvok)</translation> <translation id="7581462281756524039">Orodje za čiščenje</translation> <translation id="7582582252461552277">Prednostno uporabi to omrežje</translation> @@ -4597,7 +4576,6 @@ <translation id="8068253693380742035">Za prijavo se dotaknite</translation> <translation id="8069615408251337349">Google Tiskanje v oblaku</translation> <translation id="8071432093239591881">Natisni kot sliko</translation> -<translation id="8072988827236813198">Pripni zavihke</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Podatki aplikacij so lahko kateri koli podatki, ki jih je shranila aplikacija (glede na nastavitve razvijalca), vključno s podatki, kot so stiki, sporočila in fotografije.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Varnostno kopirani podatki se ne štejejo v otrokovo omejitev prostora za shranjevanje v Googlu Drive.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />To storitev lahko izklopite v nastavitvah.<ph name="END_PARAGRAPH3" /></translation> @@ -4783,7 +4761,6 @@ <translation id="8368859634510605990">&Odpri vse zaznamke</translation> <translation id="8371695176452482769">Začnite govoriti</translation> <translation id="8372369524088641025">Napačen ključ WEP</translation> -<translation id="8373553483208508744">Izklop zvoka zavihkov</translation> <translation id="8378714024927312812">Upravlja vaša organizacija</translation> <translation id="8379878387931047019">Ta naprava ne podpira vrste varnostnega ključa, ki ga zahteva to spletno mesto</translation> <translation id="8382913212082956454">Kopiraj &e-poštni naslov</translation> @@ -4891,7 +4868,6 @@ <translation id="8546930481464505581">Prilagajanje vrstice za dotik</translation> <translation id="8547013269961688403">Omogoči celozaslonsko lupo</translation> <translation id="85486688517848470">Če želite spremeniti delovanje tipk v zgornji vrstici, pridržite tipko za iskanje</translation> -<translation id="855081842937141170">Pripni zavihek</translation> <translation id="8551388862522347954">Licence</translation> <translation id="8553342806078037065">Upravljanje drugih oseb</translation> <translation id="8554899698005018844">Brez jezika</translation> @@ -5205,7 +5181,6 @@ <translation id="9038430547971207796">Naslednjič bo telefon odklenil napravo <ph name="DEVICE_TYPE" />. Smart Lock je mogoče izklopiti v nastavitvah.</translation> <translation id="9038649477754266430">Uporaba storitve predvidevanja za hitrejše nalaganje strani</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Izklop zvoka zavihkov</translation> <translation id="9040661932550800571">Želite posodobiti geslo za <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Dostop do lokalnih datotek v vašem računalniku je onemogočil skrbnik</translation> <translation id="9042893549633094279">Zasebnost in varnost</translation> @@ -5303,7 +5278,6 @@ <translation id="920045321358709304">Iskanje z iskalnikom <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Možnosti zaklepanja zaslona</translation> <translation id="9203398526606335860">&Profiliranje omogočeno</translation> -<translation id="9203478404496196495">Vklop zvoka zavihka</translation> <translation id="9203904171912129171">Izberite napravo</translation> <translation id="9203962528777363226">Skrbnik te naprave je onemogočil dodajanje novih uporabnikov</translation> <translation id="9213073329713032541">Namestitev je bila uspešno začeta.</translation>
diff --git a/chrome/app/resources/generated_resources_sr.xtb b/chrome/app/resources/generated_resources_sr.xtb index 3d9ad56..82724d6a 100644 --- a/chrome/app/resources/generated_resources_sr.xtb +++ b/chrome/app/resources/generated_resources_sr.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Притисните ESCAPE да бисте прескочили (само у незваничним верзијама).</translation> <translation id="1093457606523402488">Видљиве мреже:</translation> <translation id="1094607894174825014">Операција читања или писања је захтевана уз неважеће смањење на: „<ph name="DEVICE_NAME" />“.</translation> -<translation id="109758035718544977">Укључи звук сајтова</translation> <translation id="1097658378307015415">Пре пријављивања приступите као гост да бисте активирали мрежу <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Увек преводи <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Stop (Заустави)</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Прегледајте веб без чувања историје прегледања у прозору без архивирања</translation> <translation id="1213037489357051291">Отисци прстију (<ph name="NUM_FINGERPRINTS" />) су подешени</translation> <translation id="1215411991991485844">Нова апликација у позадини је додата</translation> -<translation id="1216654534877302979">Искључи звук сајтова</translation> <translation id="1216659994753476700">Жао нам је. Не можемо да приступимо профилу. Подаци и датотеке сачувани на овом уређају су изгубљени.<ph name="BR" /> <ph name="BR" /> Мораћете да поново подесите профил.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Складиштите податке на налогу Google диска</translation> <translation id="1288037062697528143">Ноћно светло се аутоматски укључује када сунце зађе</translation> <translation id="1288300545283011870">Својства говора</translation> -<translation id="1293177648337752319">Укључи звук сајта</translation> <translation id="1293264513303784526">Уређај са USB прикључком типа C (леви порт)</translation> <translation id="1293556467332435079">Датотеке</translation> <translation id="1296497012903089238">Тип сертификата</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Почетна страница је страница Нова картица</translation> <translation id="1436671784520050284">Настави са подешавањем</translation> <translation id="1436784010935106834">Уклоњено</translation> -<translation id="1438632560381091872">Укључи звук картица</translation> <translation id="1442392616396121389">Префикс за усмеравање</translation> <translation id="144283815522798837">Изабраних ставки: <ph name="NUMBER_OF_ITEMS_SELECTED" /></translation> <translation id="1444628761356461360">Овим подешавањем управља власник уређаја, <ph name="OWNER_EMAIL" />.</translation> @@ -385,7 +381,6 @@ <translation id="1567387640189251553">Нека друга тастатура је повезана откако сте последњи пут унели лозинку. Можда покушава да украде вашу комбинацију тастера.</translation> <translation id="1567750922576943685">Потврда идентитета помаже у заштити личних података</translation> <translation id="1567993339577891801">JavaScript конзола</translation> -<translation id="1568067597247500137">Искључи звук сајта</translation> <translation id="1568323446248056064">Отвори подешавања уређаја за екран</translation> <translation id="1572266655485775982">Омогући Wi-Fi</translation> <translation id="1572585716423026576">Постави као позадину</translation> @@ -437,7 +432,6 @@ <translation id="1643072738649235303">Потпис X9.62 ECDSA путем SHA-1</translation> <translation id="1644574205037202324">Историја</translation> <translation id="1645516838734033527">Да би штитио <ph name="DEVICE_TYPE" />, Smart Lock захтева да имате закључавање екрана на телефону.</translation> -<translation id="1646102270785326155">Све датотеке и локални подаци повезани са овим корисником ће бити трајно избрисани када га уклоните. $1 и даље може да се пријави касније.</translation> <translation id="1646982517418478057">Унесите лозинку да бисте шифровали овај сертификат</translation> <translation id="164814987133974965">Корисник под надзором може да истражује веб уз ваше савете. Као менаџер корисника под надзором, можете <ph name="BEGIN_BOLD" />да дозвољавате или забрањујете<ph name="END_BOLD" /> одређене веб-сајтове, @@ -496,7 +490,6 @@ <translation id="1729533290416704613">Контролише и страницу која се приказује када претражујете из омнибокса.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Да бисте уклонили апликације, идите у одељак Подешавања > Google Play продавница > Управљајте Android подешавањима > Апликације или Менаџер апликација. Додирните апликацију коју желите да деинсталирате (можда ћете морати да превучете надесно или налево да бисте пронашли апликацију). Онда додирните Деинсталирај или Онемогући.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Шаље се захтев...</translation> -<translation id="1732215134274276513">Откачи картице</translation> <translation id="1733383495376208985">Шифрујте синхронизоване податке помоћу сопствене <ph name="BEGIN_LINK" />приступне фразе за синхронизацију<ph name="END_LINK" />. То не обухвата начине плаћања и адресе из Google Pay-а.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> можда неће моћи да се ажурира</translation> <translation id="1736419249208073774">Истражи</translation> @@ -548,7 +541,6 @@ <translation id="1807938677607439181">Све датотеке</translation> <translation id="1809734401532861917">Додај обележиваче, историју, лозинке и друга подешавања на <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Преглед није доступан</translation> -<translation id="1812631533912615985">Откачи картице</translation> <translation id="1813278315230285598">Услуге</translation> <translation id="18139523105317219">Име EDI стране</translation> <translation id="1815083418640426271">Налепи као чисти текст</translation> @@ -707,7 +699,6 @@ <translation id="2065405795449409761">Софтвер за аутоматизовано тестирање контролише Chrome.</translation> <translation id="2070909990982335904">Називи који почињу тачком резервисани су за систем. Изаберите други назив.</translation> <translation id="2071393345806050157">Нема локалне датотеке евиденције.</translation> -<translation id="2074527029802029717">Откачи картицу</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% батерије</translation> <translation id="2075959085554270910">Омогућавају вам да омогућите/онемогућите функције Додирни за клик и Превлачење додиром</translation> <translation id="2076269580855484719">Сакриј овај додатак</translation> @@ -1348,7 +1339,6 @@ <translation id="3045447014237878114">Овај сајт је аутоматски преузео више датотека</translation> <translation id="3046910703532196514">Веб-страница, комплетна</translation> <translation id="304747341537320566">Механизми говора</translation> -<translation id="304826556400666995">Укључи звук картица</translation> <translation id="3053013834507634016">Употреба кључа сертификата</translation> <translation id="3057861065630527966">Направите резервне копије слика и видео снимака</translation> <translation id="3060379269883947824">Омогући услугу Изаберите за говор</translation> @@ -2331,7 +2321,6 @@ <translation id="4628762811416793313">Подешавање Linux контејнера није довршено. Пробајте поново.</translation> <translation id="4628948037717959914">Слика</translation> <translation id="4631887759990505102">Извођач</translation> -<translation id="4632483769545853758">Укључи звук картице</translation> <translation id="4633003931260532286">Додатак захтева „<ph name="IMPORT_NAME" />“ чија је најстарија верзија „<ph name="IMPORT_VERSION" />“, али инсталирана је само верзија „<ph name="INSTALLED_VERSION" />“</translation> <translation id="4634771451598206121">Пријави ме поново...</translation> <translation id="4635398712689569051">Страница <ph name="PAGE_NAME" /> није доступна корисницима у режиму госта.</translation> @@ -2395,7 +2384,6 @@ <translation id="4735803855089279419">Систем није успео да одреди идентификаторе за овај уређај.</translation> <translation id="4737715515457435632">Повежите се са мрежом</translation> <translation id="473775607612524610">Ажурирај</translation> -<translation id="474217410105706308">Искључи звук картице</translation> <translation id="4742746985488890273">Закачи на полицу</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Сазнајте како да ажурирате апликације<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Поруке</translation> @@ -2620,7 +2608,6 @@ <translation id="5094721898978802975">Комуникација са основним апликацијама за сарадњу</translation> <translation id="5097002363526479830">Повезивање са мрежом „<ph name="NAME" />“ није успело: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Отвори све обележиваче</translation> -<translation id="5105855035535475848">Закачи картице</translation> <translation id="5108967062857032718">Подешавања – Уклони Android апликације</translation> <translation id="5109044022078737958">Мија</translation> <translation id="5111692334209731439">&Менаџер обележивача</translation> @@ -2685,7 +2672,6 @@ <translation id="520621735928254154">Грешка при увозу сертификата</translation> <translation id="5209320130288484488">Није пронађен ниједан уређај</translation> <translation id="5209518306177824490">SHA-1 Fingerprint</translation> -<translation id="5210365745912300556">Затвори картицу</translation> <translation id="5213481667492808996">Услуга преноса података „<ph name="NAME" />“ је спремна за коришћење</translation> <translation id="5213891612754844763">Прикажи подешавања проксија</translation> <translation id="521582610500777512">Слика је одбачена</translation> @@ -2736,7 +2722,6 @@ <translation id="5270167208902136840">Прикажи још апликација (<ph name="NUMBER_OF_MORE_APPS" />)</translation> <translation id="5275352920323889391">Пас</translation> <translation id="5275973617553375938">Враћене датотеке са Google диска</translation> -<translation id="527605719918376753">Искључи звук картице</translation> <translation id="527605982717517565">Увек дозволи JavaScript на сајту <ph name="HOST" /></translation> <translation id="5280426389926346830">Желите ли да направите пречицу?</translation> <translation id="528208740344463258">Да бисте преузели и користили Android апликације, прво треба да инсталирате ово обавезно ажурирање. Док се <ph name="DEVICE_TYPE" /> ажурира, не можете да га користите. Кад се инсталација доврши, <ph name="DEVICE_TYPE" /> ће се рестартовати.</translation> @@ -2859,7 +2844,6 @@ <translation id="5449551289610225147">Неважећа лозинка</translation> <translation id="5449588825071916739">Обележи све картице</translation> <translation id="5449716055534515760">Close Win&dow (Затвори прозор)</translation> -<translation id="5453029940327926427">Затвори картице</translation> <translation id="5454166040603940656">са добављачем <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Неважеће</translation> <translation id="5457459357461771897">Читање слика, музике и других медија са рачунара и брисање тих медија</translation> @@ -3326,7 +3310,6 @@ <translation id="6122875415561139701">Операција писања није дозвољена на: „<ph name="DEVICE_NAME" />“.</translation> <translation id="6124650939968185064">Следећи додаци зависе од овог додатка:</translation> <translation id="6125479973208104919">Нажалост, треба поново да додате налог на овај <ph name="DEVICE_TYPE" />.</translation> -<translation id="612596694132302162">Укључи звук сајта</translation> <translation id="6129691635767514872">Изабрани подаци су уклоњени из Chrome-а и са синхронизованих уређаја. Google налог можда има друге облике историје прегледања, попут претрага и активности на другим Google услугама на <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Коментар Netscape сертификата</translation> <translation id="6129953537138746214">Размак</translation> @@ -3529,7 +3512,6 @@ <translation id="6436164536244065364">Прикажи у Веб продавници</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – Пушта се аудио садржај</translation> <translation id="6442187272350399447">Изузетни</translation> -<translation id="6442697326824312960">Откачи картицу</translation> <translation id="6444070574980481588">Подесите датум и време</translation> <translation id="6445450263907939268">Ако нисте желели ове промене, можете да вратите претходна подешавања.</translation> <translation id="6447842834002726250">Колачићи</translation> @@ -3732,7 +3714,6 @@ <translation id="6770664076092644100">Потврди помоћу NFC-а</translation> <translation id="6771503742377376720">Јесте ауторитет за издавање сертификата</translation> <translation id="6777817260680419853">Преусмеравање је блокирано</translation> -<translation id="6778959797435875428">Укључи звук сајтова</translation> <translation id="677965093459947883">Јако мали</translation> <translation id="6780439250949340171">да управљате другим подешавањима</translation> <translation id="6781284683813954823">Линк дудл логотипа</translation> @@ -4049,7 +4030,6 @@ <translation id="7257666756905341374">Читање података које прекопирате</translation> <translation id="7258697411818564379">PIN је додат</translation> <translation id="7262004276116528033">Ову услугу пријављивања хостује <ph name="SAML_DOMAIN" />.</translation> -<translation id="7268365133021434339">Затвори картице</translation> <translation id="7268659760406822741">Доступне услуге</translation> <translation id="7270858098575133036">Питај када сајт жели да користи ексклузивне поруке система за приступ MIDI уређајима</translation> <translation id="7272674038937250585">Није наведен ниједан опис</translation> @@ -4239,7 +4219,6 @@ <translation id="7576032389798113292">6×4</translation> <translation id="7576690715254076113">Упари</translation> <translation id="7576976045740938453">Дошло је до проблема са налогом за режим демонстрације.</translation> -<translation id="7579149537961810247">Искључи звук сајтова</translation> <translation id="7580671184200851182">Пуштај исти звук на свим звучницима (моно звук)</translation> <translation id="7581462281756524039">Алатка за чишћење</translation> <translation id="7582582252461552277">Подеси као приоритетну мрежу</translation> @@ -4593,7 +4572,6 @@ <translation id="8068253693380742035">Додирните да бисте се пријавили</translation> <translation id="8069615408251337349">Google Cloud штампање</translation> <translation id="8071432093239591881">Одштампај као слику</translation> -<translation id="8072988827236813198">Закачи картице</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Подаци апликација могу да буду било који подаци које је апликација сачувала (на основу подешавања програмера), укључујући податке као што су контакти, поруке и слике.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Резервне копије података се не рачунају у односу на квоту меморијског простора на Диску детета.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Ову услугу можете да искључите у Подешавањима.<ph name="END_PARAGRAPH3" /></translation> @@ -4779,7 +4757,6 @@ <translation id="8368859634510605990">&Отвори све обележиваче</translation> <translation id="8371695176452482769">Почните да говорите</translation> <translation id="8372369524088641025">Неисправна WEP шифра</translation> -<translation id="8373553483208508744">Искључи звук картица</translation> <translation id="8378714024927312812">Овим управља организација</translation> <translation id="8379878387931047019">Овај уређај не подржава тип безбедносног кључа који захтева овај веб-сајт</translation> <translation id="8382913212082956454">Копирај &е-адресу</translation> @@ -4887,7 +4864,6 @@ <translation id="8546930481464505581">Прилагоди додирну траку</translation> <translation id="8547013269961688403">Омогући лупу за цео екран</translation> <translation id="85486688517848470">Задржите тастер за претрагу да бисте променили понашање тастера у горњем реду</translation> -<translation id="855081842937141170">Закачи картицу</translation> <translation id="8551388862522347954">Лиценце</translation> <translation id="8553342806078037065">Управљање другим људима</translation> <translation id="8554899698005018844">Без језика</translation> @@ -5201,7 +5177,6 @@ <translation id="9038430547971207796">Следећи пут ће телефон откључати <ph name="DEVICE_TYPE" />. Искључите Smart Lock у подешавањима.</translation> <translation id="9038649477754266430">Користите услугу предвиђања да бисте брже учитавали странице</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Искључи звук картица</translation> <translation id="9040661932550800571">Желите ли да ажурирате лозинку за <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Администратор је онемогућио приступ локалним датотекама на рачунару</translation> <translation id="9042893549633094279">Приватност и безбедност</translation> @@ -5299,7 +5274,6 @@ <translation id="920045321358709304">Претражи <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Опције закључавања екрана</translation> <translation id="9203398526606335860">&Профилисање је омогућено</translation> -<translation id="9203478404496196495">Укључи звук картице</translation> <translation id="9203904171912129171">Изаберите уређај</translation> <translation id="9203962528777363226">Администратор овог уређаја је онемогућио додавање нових корисника</translation> <translation id="9213073329713032541">Инсталација је започета.</translation>
diff --git a/chrome/app/resources/generated_resources_sv.xtb b/chrome/app/resources/generated_resources_sv.xtb index a6d47a7..09599293 100644 --- a/chrome/app/resources/generated_resources_sv.xtb +++ b/chrome/app/resources/generated_resources_sv.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Tryck på Esc om du vill hoppa över (endast versioner som inte är officiella).</translation> <translation id="1093457606523402488">Synliga nätverk:</translation> <translation id="1094607894174825014">Läs- eller skrivåtgärden begärdes med en ogiltig offset på: <ph name="DEVICE_NAME" />.</translation> -<translation id="109758035718544977">Ta fram dolda webbplatser</translation> <translation id="1097658378307015415">Aktivera nätverket <ph name="NETWORK_ID" /> genom att logga in som gäst innan du loggar in</translation> <translation id="1103523840287552314">Översätt alltid <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Stopp</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Surfa utan att någon webbhistorik sparas med ett inkognitofönster</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> fingeravtryck har konfigurerats</translation> <translation id="1215411991991485844">En ny bakgrundsapp har lagts till</translation> -<translation id="1216654534877302979">Dölj webbplatser</translation> <translation id="1216659994753476700">Tyvärr går profilen inte att läsa. Filer och data som sparats på enheten kan ha försvunnit.<ph name="BR" /> <ph name="BR" /> Du måste konfigurera profilen på nytt.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Spara data i Google Drive-kontot</translation> <translation id="1288037062697528143">Nattljuset tänds automatiskt vid solnedgången</translation> <translation id="1288300545283011870">Talegenskaper</translation> -<translation id="1293177648337752319">Sätt på webbplatsens ljud</translation> <translation id="1293264513303784526">USB-C-enhet (vänster port)</translation> <translation id="1293556467332435079">Filer</translation> <translation id="1296497012903089238">Certifikattyp</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Startsidan är sidan Ny flik</translation> <translation id="1436671784520050284">Fortsätt med konfigurationen</translation> <translation id="1436784010935106834">Borttagna</translation> -<translation id="1438632560381091872">Slå på ljud från flikar</translation> <translation id="1442392616396121389">Dirigeringsprefix</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> markerade</translation> <translation id="1444628761356461360">Den här inställningen hanteras av enhetens ägare, <ph name="OWNER_EMAIL" />.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Ett annat tangentbord har anslutits sedan du senast angav lösenordet. Det kan försöka stjäla dina tangenttryckningar.</translation> <translation id="1567750922576943685">Skydda personliga uppgifter genom att verifiera din identitet</translation> <translation id="1567993339577891801">JavaScript-konsol</translation> -<translation id="1568067597247500137">Stäng av webbplatsens ljud</translation> <translation id="1568323446248056064">Öppna enhetsinställningarna för skärm</translation> <translation id="1572266655485775982">Aktivera Wi-Fi</translation> <translation id="1572585716423026576">Använd som bakgrund</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">X9.62 ECDSA-signatur med SHA-1</translation> <translation id="1644574205037202324">Historik</translation> <translation id="1645516838734033527">Mobilen behöver ha ett skärmlås när du använder Smart Lock så att din <ph name="DEVICE_TYPE" /> förblir skyddad.</translation> -<translation id="1646102270785326155">Alla filer och all lokal data som är kopplade till den här användaren raderas permanent när användaren tas bort. $1 kan fortfarande logga in senare.</translation> <translation id="1646982517418478057">Ange ett lösenord om du vill kryptera det här certifikatet</translation> <translation id="164814987133974965">En kontrollerad användare kan utforska webben med din hjälp. Som ansvarig hanterare för en kontrollerad användare kan du <ph name="BEGIN_BOLD" />tillåta eller förbjuda<ph name="END_BOLD" /> vissa webbplatser, @@ -498,7 +492,6 @@ <translation id="1729533290416704613">Det styr också vilken sida som visas när du söker i adressfältet.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Om du vill ta bort appar öppnar du Inställningar > Google Play Butik > Hantera Android-inställningar > Appar eller Apphanteraren. Tryck sedan på appen du vill avinstallera (du kanske måste svepa åt höger eller vänster för att hitta appen). Tryck sedan på Avinstallera eller Inaktivera.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Skickar begäran...</translation> -<translation id="1732215134274276513">Lossa flikar</translation> <translation id="1733383495376208985">Kryptera synkroniserad data med en egen <ph name="BEGIN_LINK" />lösenfras för synkronisering<ph name="END_LINK" />. Betalningsmetoder och adresser från Google Pay omfattas inte.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> kanske inte kan uppdateras automatiskt</translation> <translation id="1736419249208073774">Utforska</translation> @@ -550,7 +543,6 @@ <translation id="1807938677607439181">Alla filer</translation> <translation id="1809734401532861917">Lägg till bokmärken, historik, lösenord och andra inställningar i <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Ingen förhandsgranskning</translation> -<translation id="1812631533912615985">Lossa flikar</translation> <translation id="1813278315230285598">Tjänster</translation> <translation id="18139523105317219">EDI-partsnamn</translation> <translation id="1815083418640426271">Klistra in som oformaterad text</translation> @@ -709,7 +701,6 @@ <translation id="2065405795449409761">Chrome kontrolleras av automatisk testprogramvara.</translation> <translation id="2070909990982335904">Namn som börjar med en punkt är reserverade för systemet. Välj ett annat namn.</translation> <translation id="2071393345806050157">Det finns ingen lokal loggfil.</translation> -<translation id="2074527029802029717">Lossa flik</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" /> % batteri</translation> <translation id="2075959085554270910">Gör det möjligt att aktivera/inaktivera lätt klick på styrplattan samt trycka och dra</translation> <translation id="2076269580855484719">Dölj det här plugin-programmet</translation> @@ -1351,7 +1342,6 @@ <translation id="3045447014237878114">Den här webbplatsen laddade ned flera filer automatiskt</translation> <translation id="3046910703532196514">Webbsida, komplett</translation> <translation id="304747341537320566">Talmotorer</translation> -<translation id="304826556400666995">Slå på ljud från flikar</translation> <translation id="3053013834507634016">Certifikatnyckelanvändning</translation> <translation id="3057861065630527966">Säkerhetskopiera foton och videor</translation> <translation id="3060379269883947824">Aktivera Textuppläsning</translation> @@ -2334,7 +2324,6 @@ <translation id="4628762811416793313">Det gick inte att slutföra konfigureringen av Linux-behållaren. Försök igen.</translation> <translation id="4628948037717959914">Foto</translation> <translation id="4631887759990505102">Artist</translation> -<translation id="4632483769545853758">Slå på ljud från flik</translation> <translation id="4633003931260532286">Tillägget kräver <ph name="IMPORT_NAME" /> med minst version <ph name="IMPORT_VERSION" />, men endast version <ph name="INSTALLED_VERSION" /> är installerad</translation> <translation id="4634771451598206121">Logga in igen ...</translation> <translation id="4635398712689569051">Sidan <ph name="PAGE_NAME" /> är inte tillgänglig för gästanvändare.</translation> @@ -2398,7 +2387,6 @@ <translation id="4735803855089279419">Det gick inte att fastställa enhets-id för den här enheten.</translation> <translation id="4737715515457435632">Anslut till ett nätverk</translation> <translation id="473775607612524610">Uppdatera</translation> -<translation id="474217410105706308">Stäng av ljud från flik</translation> <translation id="4742746985488890273">Fäst på hyllan</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Läs mer om hur du uppdaterar appar<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Meddelanden</translation> @@ -2623,7 +2611,6 @@ <translation id="5094721898978802975">Kommunicera med samverkande inbyggda appar</translation> <translation id="5097002363526479830">Det gick inte att ansluta till nätverket <ph name="NAME" />: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Öppna alla bokmärken</translation> -<translation id="5105855035535475848">Fäst flikar</translation> <translation id="5108967062857032718">Inställningar – ta bort Android-appar</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">&Bokmärkeshanteraren</translation> @@ -2688,7 +2675,6 @@ <translation id="520621735928254154">Fel vid import av certifikat</translation> <translation id="5209320130288484488">Det gick inte att hitta några enheter</translation> <translation id="5209518306177824490">SHA-1-fingeravtryck</translation> -<translation id="5210365745912300556">Stäng flik</translation> <translation id="5213481667492808996">Datatjänsten <ph name="NAME" /> är klar att använda</translation> <translation id="5213891612754844763">Visa proxyinställningar</translation> <translation id="521582610500777512">Bilden togs bort</translation> @@ -2739,7 +2725,6 @@ <translation id="5270167208902136840">Visa <ph name="NUMBER_OF_MORE_APPS" /> fler appar</translation> <translation id="5275352920323889391">Hund</translation> <translation id="5275973617553375938">Återställda filer från Google Drive</translation> -<translation id="527605719918376753">Stäng av ljud från flik</translation> <translation id="527605982717517565">Tillåt alltid JavaScript på <ph name="HOST" /></translation> <translation id="5280426389926346830">Vill du skapa en genväg?</translation> <translation id="528208740344463258">Om du vill ladda ned och använda Android-appar måste du först installera den här obligatoriska uppdateringen. Du kan inte använda <ph name="DEVICE_TYPE" /> medan uppdateringen installeras. <ph name="DEVICE_TYPE" /> startas om när installationen är slutförd.</translation> @@ -2862,7 +2847,6 @@ <translation id="5449551289610225147">Ogiltigt lösenord</translation> <translation id="5449588825071916739">Skapa bokmärken för alla flikar</translation> <translation id="5449716055534515760">Stäng fön&ster</translation> -<translation id="5453029940327926427">Stäng flikar</translation> <translation id="5454166040603940656">med <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Ogiltigt</translation> <translation id="5457459357461771897">Läsa och ta bort foton, musik och andra media från datorn</translation> @@ -3327,7 +3311,6 @@ <translation id="6122875415561139701">Skrivbehörigheten för åtgärden saknas på: <ph name="DEVICE_NAME" />.</translation> <translation id="6124650939968185064">Följande tillägg är beroende av detta tillägg:</translation> <translation id="6125479973208104919">Du måste tyvärr lägga till ditt konto på <ph name="DEVICE_TYPE" /> igen.</translation> -<translation id="612596694132302162">Sätt på webbplatsens ljud</translation> <translation id="6129691635767514872">Den data som markerades har tagits bort från Chrome och från synkroniserade enheter. Det kan finnas webbhistorik av annat slag i Google-kontot på <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />, t.ex. sökningar och aktivitet på andra tjänster från Google.</translation> <translation id="6129938384427316298">Kommentar för Netscape-certifikat</translation> <translation id="6129953537138746214">Blanksteg</translation> @@ -3530,7 +3513,6 @@ <translation id="6436164536244065364">Visa i Web Store</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – spelar upp ljud</translation> <translation id="6442187272350399447">Fenomenal</translation> -<translation id="6442697326824312960">Lossa flik</translation> <translation id="6444070574980481588">Ange datum och tid</translation> <translation id="6445450263907939268">Om du inte vill ha dessa ändringar kan du återställa dina tidigare inställningar.</translation> <translation id="6447842834002726250">Cookies</translation> @@ -3733,7 +3715,6 @@ <translation id="6770664076092644100">Verifiera via NFC</translation> <translation id="6771503742377376720">Är en certifikatutfärdare</translation> <translation id="6777817260680419853">Omdirigeringen blockerades</translation> -<translation id="6778959797435875428">Ta fram dolda webbplatser</translation> <translation id="677965093459947883">Mycket liten</translation> <translation id="6780439250949340171">hantera andra inställningar</translation> <translation id="6781284683813954823">Länk till doodlen</translation> @@ -4050,7 +4031,6 @@ <translation id="7257666756905341374">Läsa data som du kopierar och klistrar in</translation> <translation id="7258697411818564379">Pinkoden har lagts till</translation> <translation id="7262004276116528033">Inloggningstjänsten tillhandahålls av <ph name="SAML_DOMAIN" />.</translation> -<translation id="7268365133021434339">Stäng flikar</translation> <translation id="7268659760406822741">Tillgängliga tjänster</translation> <translation id="7270858098575133036">Fråga när en webbplats vill använda systemexklusiva meddelanden för att komma åt MIDI-enheter</translation> <translation id="7272674038937250585">Ingen beskrivning har angetts</translation> @@ -4240,7 +4220,6 @@ <translation id="7576032389798113292">6:4</translation> <translation id="7576690715254076113">Jämför</translation> <translation id="7576976045740938453">Ett problem uppstod med kontot för demoläge.</translation> -<translation id="7579149537961810247">Dölj webbplatser</translation> <translation id="7580671184200851182">Spela samma ljud i alla högtalare (monoljud)</translation> <translation id="7581462281756524039">Ett rensningsverktyg</translation> <translation id="7582582252461552277">Föredra det här nätverket</translation> @@ -4594,7 +4573,6 @@ <translation id="8068253693380742035">Tryck här om du vill logga in</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Skriv ut som bild</translation> -<translation id="8072988827236813198">Fäst flikar</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Appdata är all data som har sparats i en app (utifrån utvecklarens inställningar), till exempel kontakter, meddelanden och foton.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Säkerhetskopierad data tar inte upp något av ditt barns lagringsutrymme på Drive.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Du kan inaktivera den här tjänsten i inställningarna.<ph name="END_PARAGRAPH3" /></translation> @@ -4780,7 +4758,6 @@ <translation id="8368859634510605990">&Öppna alla bokmärken</translation> <translation id="8371695176452482769">Prata nu</translation> <translation id="8372369524088641025">Felaktig WEP-nyckel</translation> -<translation id="8373553483208508744">Stäng av ljud från flikar</translation> <translation id="8378714024927312812">Hanteras av organisationen</translation> <translation id="8379878387931047019">Enheten stöder inte den typ av säkerhetsnyckel som begärs av webbplatsen</translation> <translation id="8382913212082956454">Kopiera &e-postadress</translation> @@ -4888,7 +4865,6 @@ <translation id="8546930481464505581">Anpassa pekfältet</translation> <translation id="8547013269961688403">Aktivera helskärmsförstorare</translation> <translation id="85486688517848470">Håll ned söktangenten om du vill ändra funktionen för tangenterna på översta raden</translation> -<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> @@ -5202,7 +5178,6 @@ <translation id="9038430547971207796">Nästa gång låser mobilen upp din <ph name="DEVICE_TYPE" />. Du kan inaktivera Smart Lock i inställningarna.</translation> <translation id="9038649477754266430">Använd en förslagstjänst om du vill läsa in sidor snabbare</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Stäng av ljud från flikar</translation> <translation id="9040661932550800571">Vill du uppdatera lösenordet för <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Administratören har inaktiverat åtkomsten till lokala filer på datorn</translation> <translation id="9042893549633094279">Sekretess och säkerhet</translation> @@ -5300,7 +5275,6 @@ <translation id="920045321358709304">Sök på <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Alternativ för skärmlås</translation> <translation id="9203398526606335860">&Profilering aktiverad</translation> -<translation id="9203478404496196495">Slå på ljud från flik</translation> <translation id="9203904171912129171">Välj en enhet</translation> <translation id="9203962528777363226">Administratören av den här enheten har inaktiverat nya användare från att läggas till</translation> <translation id="9213073329713032541">Installationen har påbörjats.</translation>
diff --git a/chrome/app/resources/generated_resources_sw.xtb b/chrome/app/resources/generated_resources_sw.xtb index fc4c242..61663b54 100644 --- a/chrome/app/resources/generated_resources_sw.xtb +++ b/chrome/app/resources/generated_resources_sw.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Bonyeza ESCAPE ili kuruka (Vijenzi visivyo rasmi pekee).</translation> <translation id="1093457606523402488">Mitandao Inayoonekana:</translation> <translation id="1094607894174825014">Shughuli za kusoma au kuandika ziliombwa kwa kutumia nambari isiyo sahihi kwenye : "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">Washa Sauti za Tovuti</translation> <translation id="1097658378307015415">Kabla ya kuingia, tafadhali ingia kama Mgeni ili kuamilisha mtandao <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Tafsiri <ph name="LANGUAGE" /> kila wakati</translation> <translation id="1108600514891325577">&Acha</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Tumia wavuti bila kuhifadhi historia yako ya kuvinjari kwa kutumia dirisha fiche</translation> <translation id="1213037489357051291">Umeweka alama <ph name="NUM_FINGERPRINTS" /> za vidole</translation> <translation id="1215411991991485844">Programu mpya ya mandharinyuma imeongezwa</translation> -<translation id="1216654534877302979">Zima sauti za tovuti</translation> <translation id="1216659994753476700">Samahani. Tumeshindwa kufikia wasifu wako. Faili na data zilizohifadhiwa kwenye kifaa hiki zimepotea.<ph name="BR" /> <ph name="BR" /> Itabidi uweke mipangilio ya wasifu wako tena.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Hifadhi data katika akaunti yako ya Hifadhi ya Google</translation> <translation id="1288037062697528143">Kipengele cha Mwanga wa Usiku kitawaka kiotomatiki wakati wa machweo</translation> <translation id="1288300545283011870">Sifa za Sauti</translation> -<translation id="1293177648337752319">Washa Sauti ya Tovuti</translation> <translation id="1293264513303784526">Kifaa cha USB-C (mlango wa kushoto)</translation> <translation id="1293556467332435079">Faili</translation> <translation id="1296497012903089238">Aina ya Cheti</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Ukurasa wa Mwanzo ndio ukurasa wa kichupo kipya</translation> <translation id="1436671784520050284">Endelea kuweka mipangilio</translation> <translation id="1436784010935106834">Zimeondolewa</translation> -<translation id="1438632560381091872">Rejesha sauti ya vichupo</translation> <translation id="1442392616396121389">Kiambishi awali cha ruta</translation> <translation id="144283815522798837">Umechagua vipengee <ph name="NUMBER_OF_ITEMS_SELECTED" /></translation> <translation id="1444628761356461360">Mpangilio huu unasimamiwa na mmiliki wa kifaa, <ph name="OWNER_EMAIL" />.</translation> @@ -385,7 +381,6 @@ <translation id="1567387640189251553">Kibodi tofauti imeunganishwa baada ya tukio lako la hivi karibuni la kuweka nenosiri. Huenda inajaribu kuiba mibofyo yako.</translation> <translation id="1567750922576943685">Hatua ya kuthibitisha utambulisho wako inasaidia kulinda taarifa zako za binafsi</translation> <translation id="1567993339577891801">Kidhibiti JavaScript</translation> -<translation id="1568067597247500137">Zima sauti ya tovuti</translation> <translation id="1568323446248056064">Fungua mipangilio ya kifaa ya onyesho</translation> <translation id="1572266655485775982">Washa Wi-Fi</translation> <translation id="1572585716423026576">Weka kama mandhari</translation> @@ -437,7 +432,6 @@ <translation id="1643072738649235303">Sahihi ya X9.62 ECDSA yenye SHA-1</translation> <translation id="1644574205037202324">Historia</translation> <translation id="1645516838734033527">Ili kuweka kifaa chako cha <ph name="DEVICE_TYPE" /> salama, weka mipangilio ya kufunga skrini kwenye simu yako ili uweze kutumia Smart Lock.</translation> -<translation id="1646102270785326155">Faili na data zote zilizo kwenye kifaa zinazohusishwa na mtumiaji zitafutwa kabisa mtumiaji huyu atakapoondolewa. $1 bado anaweza kuingia katika akaunti baadaye.</translation> <translation id="1646982517418478057">Tafadhali weka nenosiri ili usimbe cheti hii kwa njia fiche</translation> <translation id="164814987133974965">Mtumiaji anayesimamiwa anaweza kugundua wavuti chini ya mwongozo wako. Kama msimamizi wa mtumiaji anayesimamiwa, unaweza <ph name="BEGIN_BOLD" />kuruhusu au kuzuia<ph name="END_BOLD" /> tofuti fulani, @@ -496,7 +490,6 @@ <translation id="1729533290416704613">Pia inadhibiti ukurasa unaoonyeshwa unapotafuta kutoka Sanduku Kuu.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Ili uondoe programu, nenda kwenye Mipangilio > Duka la Google Play > Dhibiti mapendeleo ya Android > Programu au Kidhibiti cha programu. Kisha uguse programu unayotaka kuondoa (huenda utahitaji kutelezesha kidole kulia au kushoto ili upate programu). Kisha uguse Ondoa au Zima.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Ombi linatumwa...</translation> -<translation id="1732215134274276513">Banua Vichupo</translation> <translation id="1733383495376208985">Simba data iliyosawazishwa kwa njia fiche ukitumia <ph name="BEGIN_LINK" />kauli yako ya siri ya usawazishaji<ph name="END_LINK" />. Hali hii haijumuishi njia za kulipa na anwani kutoka Google Pay.</translation> <translation id="1734824808160898225">Huenda <ph name="PRODUCT_NAME" /> isiweze kujisasisha.</translation> <translation id="1736419249208073774">Gundua</translation> @@ -548,7 +541,6 @@ <translation id="1807938677607439181">Faili zote</translation> <translation id="1809734401532861917">Ongeza alamisho, historia, manenosiri na mipangilio yangu mingine kwenye <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Hakuna onyesho la kuchungulia</translation> -<translation id="1812631533912615985">Banua vichupo</translation> <translation id="1813278315230285598">Huduma</translation> <translation id="18139523105317219">Jina la Sehemu ya EDI</translation> <translation id="1815083418640426271">Bandika Kama Matini Makavu</translation> @@ -707,7 +699,6 @@ <translation id="2065405795449409761">Chrome inadhibitiwa na programu otomatiki ya majaribio.</translation> <translation id="2070909990982335904">Majina yanayoanza kwa nukta yametengwa mahususi kwa mfumo. Tafadahili chagua jina jingine.</translation> <translation id="2071393345806050157">Hakuna faili ya kumbukumbu ya ndani</translation> -<translation id="2074527029802029717">Banua kichupo</translation> <translation id="2075474481720804517">Asilimia <ph name="BATTERY_PERCENTAGE" /> ya betri</translation> <translation id="2075959085554270910">Hukuruhusu uwashe/uzime kipengee cha gusa ili ubofye na kuburuta kwa kugusa</translation> <translation id="2076269580855484719">Ficha programu jalizi hii</translation> @@ -1353,7 +1344,6 @@ <translation id="3045447014237878114">Tovuti hii ilipakua faili nyingi kiotomatiki</translation> <translation id="3046910703532196514">Ukurasa wa wavuti, Umekamilika</translation> <translation id="304747341537320566">Mitambo ya Sauti</translation> -<translation id="304826556400666995">Rejesha sauti ya Vichupo</translation> <translation id="3053013834507634016">Matumizi ya Ufunguo wa Cheti</translation> <translation id="3057861065630527966">Weka hifadhi rudufu ya picha na video zako</translation> <translation id="3060379269883947824">Washa kipengele cha chagua ili izungumze</translation> @@ -2334,7 +2324,6 @@ <translation id="4628762811416793313">Imeshindwa kukamilisha kuweka mipangilio ya metadata ya Linux. Tafadhali jaribu tena.</translation> <translation id="4628948037717959914">Picha</translation> <translation id="4631887759990505102">Msanii</translation> -<translation id="4632483769545853758">Rejesha sauti ya Kichupo</translation> <translation id="4633003931260532286">Kiendelezi kinahitaji "<ph name="IMPORT_NAME" />" yenye toleo la chini zaidi la "<ph name="IMPORT_VERSION" />", lakini toleo la "<ph name="INSTALLED_VERSION" />" ndilo limesakinishwa pekee.</translation> <translation id="4634771451598206121">Ingia tena...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" /> haipatikani kwa watumiaji Wageni</translation> @@ -2399,7 +2388,6 @@ <translation id="4736292055110123391">Sawazisha historia, manenosiri, alamisho na vipengee vingine kwenye vifaa vyako vyote</translation> <translation id="4737715515457435632">Tafadhali unganisha kwenye mtandao.</translation> <translation id="473775607612524610">Sasisha</translation> -<translation id="474217410105706308">Nyamazisha Kichupo</translation> <translation id="4742746985488890273">Bandika kwenye Rafu</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Pata maelezo zaidi kuhusu jinsi ya kusasisha programu<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Ujumbe</translation> @@ -2624,7 +2612,6 @@ <translation id="5094721898978802975">Kuwasiliana na programu za asili zinazoshirikiana</translation> <translation id="5097002363526479830">Imeshindwa kuunganisha kwenye mtandao '<ph name="NAME" />': <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Fungua alamisho zote</translation> -<translation id="5105855035535475848">Bana vichupo</translation> <translation id="5108967062857032718">Mipangilio - Ondoa programu za Android</translation> <translation id="5109044022078737958">Mia</translation> <translation id="5111692334209731439">Kidhibiti &Alamisho</translation> @@ -2689,7 +2676,6 @@ <translation id="520621735928254154">Hitilafu ya Kuleta Cheti</translation> <translation id="5209320130288484488">Hakuna vifaa vilivyopatikana</translation> <translation id="5209518306177824490">Alama ya SHA-1</translation> -<translation id="5210365745912300556">Funga kichupo</translation> <translation id="5213481667492808996">Huduma yako ya data ya '<ph name="NAME" />' iko tayari kutumiwa</translation> <translation id="5213891612754844763">Onyesha mipangilio ya seva mbadala</translation> <translation id="521582610500777512">Picha ilitupwa</translation> @@ -2741,7 +2727,6 @@ <translation id="5272654297705279635">Mipangilio maalum</translation> <translation id="5275352920323889391">Mbwa</translation> <translation id="5275973617553375938">Faili zilizorejeshwa kutoka Hifadhi ya Google</translation> -<translation id="527605719918376753">Nyamazisha kichupo</translation> <translation id="527605982717517565">Ruhusu <ph name="HOST" /> iendeshe JavaScript kila wakati</translation> <translation id="5280426389926346830">Ungependa Kuweka Njia ya Mkato?</translation> <translation id="528208740344463258">Ili upakue na utumie programu za Android, unatakiwa kwanza usakinishe sasisho hili linalohitajika. Wakati unasasisha <ph name="DEVICE_TYPE" /> yako, huwezi kuitumia. Baada ya kumaliza kuisakinisha, <ph name="DEVICE_TYPE" /> yako itazima kisha iwake upya.</translation> @@ -2864,7 +2849,6 @@ <translation id="5449551289610225147">Nenosiri hilo si sahihi</translation> <translation id="5449588825071916739">Alamisha Vichupo Vyote</translation> <translation id="5449716055534515760">Funga Dirisha</translation> -<translation id="5453029940327926427">Funga vichupo</translation> <translation id="5454166040603940656">na <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Haiwezi kutumika</translation> <translation id="5457459357461771897">Soma na ufute picha, muziki, na maudhui mengine kwenye kompyuta yako</translation> @@ -3329,7 +3313,6 @@ <translation id="6122875415561139701">Shughuli za kuandika haziruhusiwi kwenye: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">Viendelezi vinavyofuata vinategemea kiendelezi hiki:</translation> <translation id="6125479973208104919">Kwa bahati mbaya, utahitaji kuongeza akaunti yako kwenye kifaa hiki cha <ph name="DEVICE_TYPE" /> tena.</translation> -<translation id="612596694132302162">Washa sauti ya tovuti</translation> <translation id="6129691635767514872">Data uliyochagua imeondolewa kwenye Chrome na kwenye vifaa vilivyosawazishwa. Huenda Akaunti yako ya Google ina aina nyingine za historia ya kuvinjari kama vile utafutaji na shughuli kutoka huduma nyingine za Google katika <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Kidokezo cha Cheti cha Netscape</translation> <translation id="6129953537138746214">Nafasi</translation> @@ -3532,7 +3515,6 @@ <translation id="6436164536244065364">Ona katika Duka la Wavuti</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - Kucheza sauti</translation> <translation id="6442187272350399447">Safi</translation> -<translation id="6442697326824312960">Banua Kichupo</translation> <translation id="6444070574980481588">Weka tarehe na saa</translation> <translation id="6445450263907939268">Kama hutaki mabadiliko haya, unaweza kurejesha mipangilio yako ya awali.</translation> <translation id="6447842834002726250">Vidakuzi</translation> @@ -3735,7 +3717,6 @@ <translation id="6770664076092644100">Thibitisha kupitia NFC</translation> <translation id="6771503742377376720">Ni Idhini ya Cheti</translation> <translation id="6777817260680419853">Imezuia shughuli ya kuelekeza kwingine</translation> -<translation id="6778959797435875428">Washa sauti za tovuti</translation> <translation id="677965093459947883">Ndogo sana</translation> <translation id="6780439250949340171">dhibiti mipangilio mingine</translation> <translation id="6781284683813954823">Kiungo cha Doodle</translation> @@ -4052,7 +4033,6 @@ <translation id="7257666756905341374">Kusoma data unayonakili na kubandika</translation> <translation id="7258697411818564379">PIN yako imeongezwa</translation> <translation id="7262004276116528033">Huduma hii ya kuingia katika akaunti inatolewa na <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Funga Vichupo</translation> <translation id="7268659760406822741">Huduma zinazopatikana</translation> <translation id="7270858098575133036">Uliza wakati tovuti inapotaka kutumia ujumbe wa kipekee wa mfumo kupata idhini ya kufikia vifaa vya MIDI</translation> <translation id="7272674038937250585">Hakuna maelezo yaliyotolewa</translation> @@ -4242,7 +4222,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">Kusanya</translation> <translation id="7576976045740938453">Hitilafu imetokea kwenye akaunti ya hali ya onyesho.</translation> -<translation id="7579149537961810247">Zima Sauti za Tovuti</translation> <translation id="7580671184200851182">Cheza sauti moja kupitia spika zote (sauti ya mono)</translation> <translation id="7581462281756524039">Zana ya kusafisha</translation> <translation id="7582582252461552277">Pendelea mtandao huu</translation> @@ -4598,7 +4577,6 @@ <translation id="8068253693380742035">Gusa ili uingie katika akaunti</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Chapisha kuwa picha</translation> -<translation id="8072988827236813198">Bana Vichupo</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Data ya programu inaweza kuwa data yoyote ambayo programu imehifadhi (kulingana na mipangilio ya msanidi programu), ikijumuisha data kama vile anwani, ujumbe na picha.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Nakala ya data iliyohifadhiwa haitahesabiwa katika mgawo wa nafasi ya Hifadhi ya mtoto wako.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Unaweza kuzima huduma hii katika Mipangilio.<ph name="END_PARAGRAPH3" /></translation> @@ -4785,7 +4763,6 @@ <translation id="8368859634510605990">&Fungua alamisho zote</translation> <translation id="8371695176452482769">Ongea sasa</translation> <translation id="8372369524088641025">Kitufe kibovu cha WEP</translation> -<translation id="8373553483208508744">Zima vichupo</translation> <translation id="8378714024927312812">Inasimamiwa na shirika lako</translation> <translation id="8379878387931047019">Kifaa hiki hakitumii aina hii ya ufunguo wa usalama ulioombwa na tovuti hii</translation> <translation id="8382913212082956454">Nakili barua p&epe</translation> @@ -4893,7 +4870,6 @@ <translation id="8546930481464505581">Badilisha Upau Mguso Utakavyo</translation> <translation id="8547013269961688403">Washa kikuzaji cha skrini nzima</translation> <translation id="85486688517848470">Shikilia kitufe cha Utafutaji ili ubadilishe tabia ya vitufe vya juu vya safu mlalo</translation> -<translation id="855081842937141170">Bandikiza kichupo</translation> <translation id="8551388862522347954">Leseni</translation> <translation id="8553342806078037065">Dhibiti watumiaji wengine</translation> <translation id="8554899698005018844">Hakuna lugha</translation> @@ -5208,7 +5184,6 @@ <translation id="9038430547971207796">Utakapoitumia tena, simu yako itaifungua <ph name="DEVICE_TYPE" /> yako. Zima Smart Lock katika Mipangilio.</translation> <translation id="9038649477754266430">Tumia huduma ya kutabiri ili upakie kurasa kwa haraka zaidi</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Nyamazisha Vichupo</translation> <translation id="9040661932550800571">Ungependa kusasisha nenosiri la <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Ufikiaji wa faili za ndani kwenye mashine yako umezimwa na msimamizi wako</translation> <translation id="9042893549633094279">Faragha na usalama</translation> @@ -5306,7 +5281,6 @@ <translation id="920045321358709304">Tafuta <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Chaguo za kufunga skrini</translation> <translation id="9203398526606335860">&Uwekaji maelezo mafupi umewezeshwa</translation> -<translation id="9203478404496196495">Rejesha sauti ya kichupo</translation> <translation id="9203904171912129171">Chagua kifaa</translation> <translation id="9203962528777363226">Msimamizi wa kifaa hiki amelemaza kuongezwa kwa watumiaji wapya</translation> <translation id="9213073329713032541">Imeanza kusakinisha.</translation>
diff --git a/chrome/app/resources/generated_resources_ta.xtb b/chrome/app/resources/generated_resources_ta.xtb index e6397f0..37aa57d 100644 --- a/chrome/app/resources/generated_resources_ta.xtb +++ b/chrome/app/resources/generated_resources_ta.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">தவிர்க்க, ESCAPE அழுத்துக (அதிகாரப்பூர்வமற்ற தொகுதிகள் மட்டும்).</translation> <translation id="1093457606523402488">தெரியும் நெட்வொர்க்குகள்:</translation> <translation id="1094607894174825014">படித்தல் அல்லது எழுதுதல் செயல்பாடு தவறான ஆஃப்செட்டுடன் கோரப்பட்ட சாதனம்: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">தளங்களில் ஒலி இயக்கு</translation> <translation id="1097658378307015415">உள்நுழைவதற்கு முன், <ph name="NETWORK_ID" /> என்ற நெட்வொர்க்கை இயக்க, விருந்தினராக நுழைக</translation> <translation id="1103523840287552314">எப்போதும் இந்த மொழியை மொழிபெயர் <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Stop</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">மறைநிலைச் சாளரம் மூலம் உங்கள் உலாவல் வரலாற்றைச் சேமிக்காமலே இணையத்தைப் பயன்படுத்தலாம்</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> கைரேகைகளை அமைத்துள்ளீர்கள்</translation> <translation id="1215411991991485844">புதிய பின்புலப் பயன்பாடு சேர்க்கப்பட்டது</translation> -<translation id="1216654534877302979">தளங்களில் ஒலியடக்கு</translation> <translation id="1216659994753476700">உங்கள் சுயவிவரத்தை எங்களால் அணுக முடியவில்லை. இந்தச் சாதனத்தில் சேமிக்கப்பட்ட கோப்புகளும் தரவும் இழக்கப்பட்டிருக்கலாம்.<ph name="BR" /> <ph name="BR" /> சுயவிவரத்தை மீண்டும் அமைக்க வேண்டும்.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">உங்கள் Google இயக்ககக் கணக்கில் தரவைச் சேமிக்கலாம்</translation> <translation id="1288037062697528143">சூரிய அஸ்தமனத்தின் போது, நைட் லைட் விருப்பம் தானாக இயக்கப்படும்</translation> <translation id="1288300545283011870">பேச்சுப் பண்புகள்</translation> -<translation id="1293177648337752319">தளத்தில் ஒலி இயக்கு</translation> <translation id="1293264513303784526">USB-C சாதனம் (இடது போர்ட்)</translation> <translation id="1293556467332435079">கோப்புகள்</translation> <translation id="1296497012903089238">சான்றிதழ் வகை</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">புதிய தாவல் பக்கமே முகப்புப் பக்கமாகும்</translation> <translation id="1436671784520050284">அமைவைத் தொடர்க</translation> <translation id="1436784010935106834">அகற்றப்பட்டது</translation> -<translation id="1438632560381091872">தாவல்களை இயக்கு</translation> <translation id="1442392616396121389">ரூட்டிங் முன்னொட்டு</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> தேர்ந்தெடுக்கப்பட்டன</translation> <translation id="1444628761356461360">இந்த அமைப்பானது சாதனத்தின் உரிமையாளரால் <ph name="OWNER_EMAIL" /> நிர்வகிக்கப்படுகிறது.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">நீங்கள் கடைசியாகக் கடவுச்சொல்லை உள்ளிட்ட பிறகு வேறொரு விசைப்பலகை இணைக்கப்பட்டுள்ளது. அது உங்கள் விசை அழுத்தங்களைத் திருட முயற்சித்துக் கொண்டிருக்கக்கூடும்.</translation> <translation id="1567750922576943685">அடையாளத்தைச் சரிபார்க்கும் செயல்பாடு, உங்கள் தனிப்பட்ட தகவலைப் பாதுகாக்க உதவும்</translation> <translation id="1567993339577891801">JavaScript கன்சோல்</translation> -<translation id="1568067597247500137">தளத்தில் ஒலியடக்கு</translation> <translation id="1568323446248056064">திரை அமைப்புகளைத் திற</translation> <translation id="1572266655485775982">வைஃபையை இயக்கு</translation> <translation id="1572585716423026576">வால்பேப்பராக அமை</translation> @@ -440,7 +435,6 @@ <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="1646982517418478057">இந்தச் சான்றிதழை என்க்ரிப்ட் செய்ய கடவுச்சொல்லை உள்ளிடவும்</translation> <translation id="164814987133974965">கண்காணிக்கப்படும் பயனர் உங்கள் வழிகாட்டுதலினால் இணையத்தைக் உலாவலாம். கண்காணிப்பு பயனரின் நிர்வாகியாக, நீங்கள் குறிப்பிட்ட இணையத்தளங்களை <ph name="BEGIN_BOLD" />அனுமதிக்கலாம் அல்லது தடுக்கலாம்<ph name="END_BOLD" />, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">சர்வபுலத்திலிருந்து தேடலை மேற்கொள்ளும்போது காண்பிக்கப்படும் பக்கத்தையும் இது கட்டுப்படுத்துகிறது.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />ஆப்ஸை அகற்ற, 'அமைப்புகள் > Google Play ஸ்டோர் > Android விருப்பத்தேர்வுகளை நிர்வகி > ஆப்ஸ் அல்லது ஆப்ஸ் நிர்வாகி’ என்பதற்குச் செல்லவும். அதில், நிறுவல் நீக்க விரும்பும் ஆப்ஸைத் தட்டவும் (ஆப்ஸைக் கண்டறிய வலப்புறம் அல்லது இடப்புறம் ஸ்வைப் செய்ய வேண்டியிருக்கலாம்). பின்னர், ‘நிறுவல் நீக்கு’ அல்லது ‘முடக்கு’ என்பதைத் தட்டவும்.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">கோரிக்கையை அனுப்புகிறது…</translation> -<translation id="1732215134274276513">தாவல்களைப் பிரித்தெடு</translation> <translation id="1733383495376208985">ஒத்திசைக்கப்பட்ட தரவை உங்கள் <ph name="BEGIN_LINK" />ஒத்திசைவுக் கடவுச்சொற்றொடர்<ph name="END_LINK" /> மூலம் என்கிரிப்ட் செய்யவும். இதில் Google Payயிலுள்ள கட்டண முறைகளும் முகவரிகளும் சேர்க்கப்படாது.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> தன்னைப் புதுப்பித்த நிலையில் வைத்துக்கொள்ள முடியாமல் போகலாம்</translation> <translation id="1736419249208073774">அறிக</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">எல்லா கோப்புகளும்</translation> <translation id="1809734401532861917"><ph name="USER_EMAIL_ADDRESS" /> இல் எனது புத்தகக்குறிகள், வரலாறு, கடவுச்சொற்கள் மற்றும் பிற அமைப்புகளைச் சேர்</translation> <translation id="1810764548349082891">மாதிரிக்காட்சி இல்லை</translation> -<translation id="1812631533912615985">தாவல்களைப் பிரித்தெடு</translation> <translation id="1813278315230285598">சேவைகள்</translation> <translation id="18139523105317219">EDI பார்ட்டி பெயர்</translation> <translation id="1815083418640426271">எளிய உரையாக ஒட்டு</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chromeஐத் தானியங்கிச் சோதனை மென்பொருள் கட்டுப்படுத்துகிறது.</translation> <translation id="2070909990982335904">புள்ளியுடன் தொடங்கும் பெயர்களை கணினி முன்பதிவு செய்துள்ளதால், வேறொரு பெயரைத் தேர்வுசெய்க.</translation> <translation id="2071393345806050157">அகப் பதிவு கோப்பு எதுவுமில்லை.</translation> -<translation id="2074527029802029717">தாவலைப் பிரித்தெடு</translation> <translation id="2075474481720804517">பேட்டரி: <ph name="BATTERY_PERCENTAGE" />%</translation> <translation id="2075959085554270910">"கிளிக் செய்ய தட்டு" மற்றும் தட்டி நகர்த்துதலை இயக்க/முடக்க உங்களை அனுமதிக்கிறது</translation> <translation id="2076269580855484719">செருகுநிரலை மறை</translation> @@ -1353,7 +1344,6 @@ <translation id="3045447014237878114">இந்தத் தளம் தானாகவே பல கோப்புகளைப் பதிவிறக்கம் செய்தது</translation> <translation id="3046910703532196514">வலைப்பக்கம், முழுமையாக</translation> <translation id="304747341537320566">பேச்சு என்ஜின்கள்</translation> -<translation id="304826556400666995">தாவல்களை இயக்கு</translation> <translation id="3053013834507634016">சான்றிதழ் விசைப் பயன்பாடு</translation> <translation id="3057861065630527966">உங்கள் படங்கள் மற்றும் வீடியோக்களைக் காப்புப் பிரதியெடுக்கவும்</translation> <translation id="3060379269883947824">பேசும் திரையை இயக்கு</translation> @@ -2335,7 +2325,6 @@ <translation id="4628762811416793313">Linux கண்டெய்னர் அமைவு முடியவில்லை. மீண்டும் முயலவும்.</translation> <translation id="4628948037717959914">படம்</translation> <translation id="4631887759990505102">கலைஞர்</translation> -<translation id="4632483769545853758">ஒலி இயக்கு</translation> <translation id="4633003931260532286">நீட்டிப்பிற்கு குறைந்தபட்சம் "<ph name="IMPORT_VERSION" />" பதிப்புடன் கூடிய "<ph name="IMPORT_NAME" />" தேவை, ஆனால் "<ph name="INSTALLED_VERSION" />" பதிப்பு மட்டும் நிறுவப்பட்டுள்ளது</translation> <translation id="4634771451598206121">மீண்டும் உள்நுழைக...</translation> <translation id="4635398712689569051">விருந்தினர் பயனர்களுக்கு <ph name="PAGE_NAME" /> கிடைக்காது.</translation> @@ -2399,7 +2388,6 @@ <translation id="4735803855089279419">இந்தச் சாதனத்திற்கான சாதன அடையாளங்காட்டிகளை சிஸ்டத்தால் தீர்மானிக்க முடியவில்லை.</translation> <translation id="4737715515457435632">நெட்வொர்க்குடன் இணைக்கவும்</translation> <translation id="473775607612524610">புதுப்பி</translation> -<translation id="474217410105706308">ஒலி வேண்டாம்</translation> <translation id="4742746985488890273">அடுக்கில் பொருத்து</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />பயன்பாடுகளைப் புதுப்பிப்பது எப்படி என்பதை அறிக<ph name="END_LINK" /></translation> <translation id="4746351372139058112">செய்திகள்</translation> @@ -2624,7 +2612,6 @@ <translation id="5094721898978802975">ஒண்றிணைந்த குறிப்பிட்ட சாதனத்திற்கான பயன்பாடுகளுடன் தொடர்புகொள்ளவும்</translation> <translation id="5097002363526479830">'<ph name="NAME" />' நெட்வொர்க்குடன் இணைய முடியவில்லை: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">புத்தகக்குறிகள் அனைத்தையும் திற</translation> -<translation id="5105855035535475848">தாவல்களைப் பொருத்து</translation> <translation id="5108967062857032718">அமைப்புகள் - Android பயன்பாடுகளை அகற்றவும்</translation> <translation id="5109044022078737958">மியா</translation> <translation id="5111692334209731439">&புக்மார்க் மேனேஜர்</translation> @@ -2689,7 +2676,6 @@ <translation id="520621735928254154">சான்றிதழ் இறக்குமதியாவதில் பிழை</translation> <translation id="5209320130288484488">சாதனங்கள் காணப்படவில்லை</translation> <translation id="5209518306177824490">SHA-1 விரல்அச்சு</translation> -<translation id="5210365745912300556">தாவலை மூடுக</translation> <translation id="5213481667492808996">இப்போது உங்கள் '<ph name="NAME" />' டேட்டா சேவையைப் பயன்படுத்தலாம்</translation> <translation id="5213891612754844763">ப்ராக்ஸி அமைப்புகளைக் காட்டு</translation> <translation id="521582610500777512">படம் விலக்கப்பட்டது</translation> @@ -2740,7 +2726,6 @@ <translation id="5270167208902136840">மேலும் <ph name="NUMBER_OF_MORE_APPS" /> ஆப்ஸைக் காட்டு</translation> <translation id="5275352920323889391">நாய்</translation> <translation id="5275973617553375938">Google இயக்கத்திலிருந்து மீட்கப்பட்ட கோப்புகள்</translation> -<translation id="527605719918376753">ஒலி வேண்டாம்</translation> <translation id="527605982717517565"><ph name="HOST" /> இல் JavaScript ஐ எப்போதும் அனுமதி</translation> <translation id="5280426389926346830">ஷார்ட்கட்டை உருவாக்கவா?</translation> <translation id="528208740344463258">Android பயன்பாடுகளைப் பதிவிறக்கிப் பயன்படுத்துவதற்கு, தேவையான புதுப்பிப்பை முதலில் நீங்கள் நிறுவ வேண்டும். உங்கள் <ph name="DEVICE_TYPE" /> புதுப்பிக்கப்படும் போது, அதை நீங்கள் பயன்படுத்த முடியாது. நிறுவல் முடிந்ததும், உங்கள் <ph name="DEVICE_TYPE" /> தொடங்கும்.</translation> @@ -2863,7 +2848,6 @@ <translation id="5449551289610225147">தவறான கடவுச்சொல்</translation> <translation id="5449588825071916739">எல்லா தாவல்களையும் புக்மார்க்கிடுக</translation> <translation id="5449716055534515760">Close Win&dow</translation> -<translation id="5453029940327926427">தாவல்களை மூடுக</translation> <translation id="5454166040603940656"><ph name="PROVIDER" /> உடன்</translation> <translation id="5457113250005438886">தவறானது</translation> <translation id="5457459357461771897">உங்கள் கணினியிலிருந்து படங்கள், இசை மற்றும் பிற மீடியாவை படிக்கலாம் மற்றும் நீக்கலாம்</translation> @@ -3329,7 +3313,6 @@ <translation id="6122875415561139701">எழுதுதல் செயல்பாடு இந்தச் சாதனத்தில் அனுமதிக்கப்படவில்லை: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">பின்வரும் நீட்டிப்புகள் இந்த நீட்டிப்பைச் சார்ந்தவை:</translation> <translation id="6125479973208104919"><ph name="DEVICE_TYPE" /> இல் உங்கள் கணக்கை மீண்டும் சேர்க்க வேண்டும்.</translation> -<translation id="612596694132302162">தளத்தில் ஒலி இயக்கு</translation> <translation id="6129691635767514872">தேர்ந்தெடுத்த தரவு, Chrome மற்றும் ஒத்திசைக்கப்பட்ட சாதனங்களிலிருந்து அகற்றப்பட்டது. உங்கள் Google கணக்கு <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> எனும் தளத்தில் பிற Google சேவைகளிலிருந்து தேடல்கள், செயல்பாடு போன்ற உலாவல் வரலாறு தொடர்பான பிற தகவல்களைக் கொண்டிருக்கலாம்.</translation> <translation id="6129938384427316298">Netscape சான்றிதழ் கருத்துரை</translation> <translation id="6129953537138746214">இடைவெளி</translation> @@ -3532,7 +3515,6 @@ <translation id="6436164536244065364">இணைய அங்காடியில் காண்க</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - ஆடியோ இயக்கப்படுகிறது</translation> <translation id="6442187272350399447">அற்புதம்</translation> -<translation id="6442697326824312960">தாவலைப் பிரித்தெடு</translation> <translation id="6444070574980481588">தேதியையும் நேரத்தையும் அமை</translation> <translation id="6445450263907939268">உங்களுக்கு இந்த மாற்றங்கள் பிடிக்கவில்லை எனில், முந்தைய அமைப்புகளை நீங்கள் மீட்டெடுக்கலாம்.</translation> <translation id="6447842834002726250">குக்கீகள்</translation> @@ -3735,7 +3717,6 @@ <translation id="6770664076092644100">NFC வழியாகச் சரிபார்</translation> <translation id="6771503742377376720">இது ஒரு சான்றளிக்கும் மையம்</translation> <translation id="6777817260680419853">திசைதிருப்புவது தடுக்கப்பட்டது</translation> -<translation id="6778959797435875428">தளங்களில் ஒலி இயக்கு</translation> <translation id="677965093459947883">மிகச் சிறியது</translation> <translation id="6780439250949340171">பிற அமைப்புகளை நிர்வகிக்கவும்</translation> <translation id="6781284683813954823">Doodle இணைப்பு</translation> @@ -4052,7 +4033,6 @@ <translation id="7257666756905341374">நீங்கள் நகலெடுத்து ஒட்டும் தரவைப் படிக்கலாம்</translation> <translation id="7258697411818564379">உங்கள் பின் சேர்க்கப்பட்டது</translation> <translation id="7262004276116528033">உள்நுழைவுச் சாதனத்தை <ph name="SAML_DOMAIN" /> ஹோஸ்ட் செய்கிறது</translation> -<translation id="7268365133021434339">தாவல்களை மூடுக</translation> <translation id="7268659760406822741">கிடைக்கும் சேவைகள்</translation> <translation id="7270858098575133036">MIDI சாதனங்களை அணுகுவதற்காக, தளமானது சாதனத்தின் தனிப்பட்ட செய்திகளைப் பயன்படுத்த விரும்பும் போது, கேள்</translation> <translation id="7272674038937250585">விளக்கம் எதுவும் வழங்கப்படவில்லை</translation> @@ -4240,7 +4220,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">ஒப்பீடு</translation> <translation id="7576976045740938453">டெமோ பயன்முறைக் கணக்கில் ஒரு சிக்கல் ஏற்பட்டது.</translation> -<translation id="7579149537961810247">தளங்களில் ஒலியடக்கு</translation> <translation id="7580671184200851182">எல்லா ஸ்பீக்கர்களிலும் ஒரே ஆடியோவை இயக்கு (மோனோ ஆடியோ)</translation> <translation id="7581462281756524039">சுத்திகரிப்புக் கருவி</translation> <translation id="7582582252461552277">இந்த நெட்வொர்க்குக்கு முன்னுரிமை வழங்குக</translation> @@ -4598,7 +4577,6 @@ <translation id="8068253693380742035">உள்நுழைய, தொடவும்</translation> <translation id="8069615408251337349">Google கிளவுடு அச்சு</translation> <translation id="8071432093239591881">படமாக அச்சிடு</translation> -<translation id="8072988827236813198">தாவல்களைப் பொருத்து</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />ஆப்ஸ் தரவு என்பது தொடர்புகள், மெசேஜ்கள், படங்கள் போன்றவை உள்ளிட்ட (டெவெலப்பர் அமைப்புகளைப் பொறுத்து) ஆப்ஸ் சேமித்த எந்தத் தரவாகவும் இருக்கலாம்.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />உங்கள் பிள்ளையின் இயக்ககச் சேமிப்பக ஒதுக்கீட்டில் காப்புப் பிரதித் தரவு கணக்கிடப்படாது.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />அமைப்புகளில் இந்தச் சேவையை முடக்கலாம்.<ph name="END_PARAGRAPH3" /></translation> @@ -4784,7 +4762,6 @@ <translation id="8368859634510605990">புக்மார்க்ஸ் அனைத்தையும் &திற</translation> <translation id="8371695176452482769">இப்போது பேசுக</translation> <translation id="8372369524088641025">மோசமான WEP விசை</translation> -<translation id="8373553483208508744">தாவல்களை முடக்கு</translation> <translation id="8378714024927312812">உங்கள் நிறுவனத்தால் நிர்வகிக்கப்படுகிறது</translation> <translation id="8379878387931047019">இந்த இணையதளம் கோரும் பாதுகாப்பு விசையின் வகையை இந்தச் சாதனம் ஆதரிக்கவில்லை</translation> <translation id="8382913212082956454">&மின்னஞ்சல் முகவரியை நகலெடு</translation> @@ -4892,7 +4869,6 @@ <translation id="8546930481464505581">டச் பாரைத் தனிப்படுத்து</translation> <translation id="8547013269961688403">முழுத்திரைப் பெரிதாக்கியை இயக்கு</translation> <translation id="85486688517848470">மேல் வரிசையில் உள்ள விசைகளின் செயல்பாட்டை மாற்ற, தேடல் விசையைப் பிடித்திருக்கவும்</translation> -<translation id="855081842937141170">தாவலைப் பொருத்து</translation> <translation id="8551388862522347954">உரிமங்கள்</translation> <translation id="8553342806078037065">பிற பயனர்களை நிர்வகி</translation> <translation id="8554899698005018844">மொழி இல்லை</translation> @@ -5206,7 +5182,6 @@ <translation id="9038430547971207796">அடுத்த முறை, உங்கள் மொபைலானது <ph name="DEVICE_TYPE" /> சாதனத்தைத் திறக்கும். அமைப்புகளுக்குச் சென்று, Smart Lockஐ முடக்கலாம்.</translation> <translation id="9038649477754266430">பக்கங்களை இன்னும் விரைவாக ஏற்ற, யூக சேவையைப் பயன்படுத்தவும்</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">தாவல்களை முடக்கு</translation> <translation id="9040661932550800571"><ph name="ORIGIN" />க்கான கடவுச்சொல்லைப் புதுப்பிக்கவா?</translation> <translation id="9041692268811217999">உங்கள் கணினியில் இருக்கும் அகக் கோப்புகளுக்கான அணுகலை நிர்வாகி முடக்கியுள்ளார்</translation> <translation id="9042893549633094279">தனியுரிமை மற்றும் பாதுகாப்பு</translation> @@ -5304,7 +5279,6 @@ <translation id="920045321358709304"><ph name="SEARCH_ENGINE" /> இல் தேடு</translation> <translation id="9201220332032049474">திரைப் பூட்டு விருப்பங்கள்</translation> <translation id="9203398526606335860">&சுயவிவரமாக்கம் இயக்கப்பட்டது</translation> -<translation id="9203478404496196495">ஒலி இயக்கு</translation> <translation id="9203904171912129171">சாதனத்தைத் தேர்ந்தெடுக்கவும்</translation> <translation id="9203962528777363226">இந்தச் சாதனத்தில் புதியவர்கள் சேர்க்கப்படுவதை இதன் நிர்வாகி முடக்கியுள்ளார்</translation> <translation id="9213073329713032541">நிறுவல் தொடங்கியது.</translation>
diff --git a/chrome/app/resources/generated_resources_te.xtb b/chrome/app/resources/generated_resources_te.xtb index 288d1e9..dab0fad 100644 --- a/chrome/app/resources/generated_resources_te.xtb +++ b/chrome/app/resources/generated_resources_te.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">దాటవేయడానికి ESCAPEను నొక్కండి (అనధికార బిల్డ్లకు మాత్రమే)</translation> <translation id="1093457606523402488">కనిపిస్తున్న నెట్వర్క్లు:</translation> <translation id="1094607894174825014">దీనిలో చెల్లని ఆఫ్సెట్తో చదివే లేదా వ్రాసే చర్య అభ్యర్థించబడింది: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">సైట్లను అన్మ్యూట్ చేయండి</translation> <translation id="1097658378307015415">సైన్ ఇన్ చేయడానికి ముందుగా, దయచేసి <ph name="NETWORK_ID" /> నెట్వర్క్ను సక్రియం చేయడానికి అతిథి వలె ప్రవేశించండి</translation> <translation id="1103523840287552314">ఎల్లప్పుడూ <ph name="LANGUAGE" />ను అనువదించు</translation> <translation id="1108600514891325577">&ఆపు</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">అజ్ఞాత విండోలో మీ బ్రౌజింగ్ చరిత్రను సేవ్ చేయకుండానే వెబ్ని ఉపయోగించండి</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> వేలిముద్రలు సెటప్ చేయబడ్డాయి</translation> <translation id="1215411991991485844">క్రొత్త నేపథ్య అనువర్తనం జోడించబడింది</translation> -<translation id="1216654534877302979">సైట్లను మ్యూట్ చేయండి</translation> <translation id="1216659994753476700">మమ్మల్ని క్షమించండి. మేము మీ ప్రొఫైల్ను ప్రాప్యత చేయలేకపోయాము. ఈ పరికరంలో నిల్వ చేయబడిన ఫైల్లు మరియు డేటా కోల్పోయి ఉండవచ్చు.<ph name="BR" /> <ph name="BR" /> మీరు మీ ప్రొఫైల్ను మళ్లీ సెటప్ చేయాల్సి ఉంటుంది.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">మీ Google డిస్క్ ఖాతాలో డేటాని నిల్వ చేయండి</translation> <translation id="1288037062697528143">సూర్యాస్తమయ సమయానికి రాత్రి కాంతి స్వయంచాలకంగా ఆన్ అవుతుంది</translation> <translation id="1288300545283011870">ప్రసంగ లక్షణాలు</translation> -<translation id="1293177648337752319">సైట్ని అన్మ్యూట్ చేయండి</translation> <translation id="1293264513303784526">USB-C పరికరం (ఎడమ పోర్ట్)</translation> <translation id="1293556467332435079">ఫైళ్ళు</translation> <translation id="1296497012903089238">ప్రమాణపత్రం రకం</translation> @@ -306,7 +303,6 @@ <translation id="1434886155212424586">హోమ్పేజీ అనేది కొత్త ట్యాబ్ పేజీ</translation> <translation id="1436671784520050284">సెటప్ని కొనసాగించు</translation> <translation id="1436784010935106834">తీసివేయబడింది</translation> -<translation id="1438632560381091872">ట్యాబ్లను అన్మ్యూట్ చేయి</translation> <translation id="1442392616396121389">రూటింగ్ ఆదిప్రత్యయం</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> ఎంచుకోబడింది/ఎంచుకోబడ్డాయి</translation> <translation id="1444628761356461360">ఈ సెట్టింగ్ను పరికరం యజమాని అయిన <ph name="OWNER_EMAIL" /> నిర్వహించారు.</translation> @@ -389,7 +385,6 @@ <translation id="1567387640189251553">మీరు మీ పాస్వర్డ్ని చివరిసారిగా నమోదు చేసిన తర్వాత ఒక విభిన్నమైన కీబోర్డ్ కనెక్ట్ చేయబడింది. మీ కీస్ట్రోక్లను దొంగిలించడం కోసం ఇది ప్రయత్నిస్తుండవచ్చు.</translation> <translation id="1567750922576943685">మీ గుర్తింపును ధృవీకరించడం ద్వారా మీ వ్యక్తిగత సమాచారాన్ని భద్రంగా కాపాడుకోవచ్చు</translation> <translation id="1567993339577891801">JavaScript కన్సోల్</translation> -<translation id="1568067597247500137">సైట్ని మ్యూట్ చేయండి</translation> <translation id="1568323446248056064">ప్రదర్శన పరికరం సెట్టింగ్లను తెరవండి</translation> <translation id="1572266655485775982">Wi-Fiని ప్రారంభించు</translation> <translation id="1572585716423026576">వాల్పేపర్గా సెట్ చేయి</translation> @@ -441,7 +436,6 @@ <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="1646982517418478057">దయచేసి ఈ ప్రమాణపత్రాన్ని గుప్తీకరించడానికి పాస్వర్డ్ని నమోదు చేయండి</translation> <translation id="164814987133974965">పర్యవేక్షించబడే వినియోగదారు మీ మార్గదర్శకత్వంలో వెబ్ను విశ్లేషించగలరు. పర్యవేక్షించబడే వినియోగదారు యొక్క నిర్వాహకునిగా, మీరు వీటిని చేయగలరు నిర్దిష్ట వెబ్సైట్లను <ph name="BEGIN_BOLD" />అనుమతించడం లేదా నిషేధించడం<ph name="END_BOLD" />, @@ -500,7 +494,6 @@ <translation id="1729533290416704613">ఇది ఓమ్నిపెట్టె నుండి శోధించేటప్పుడు చూపబడే పేజీని కూడా నియంత్రిస్తుంది.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />యాప్లను తీసివేయడానికి, సెట్టింగ్లు > Google Play స్టోర్ > Android ప్రాధాన్యతలను నిర్వహించు > యాప్లు లేదా అప్లికేషన్ మేనేజర్కి వెళ్లండి. ఆ తర్వాత, మీరు అన్ఇన్స్టాల్ చేయాలనుకుంటున్న యాప్ని నొక్కండి (మీరు యాప్ని కనుగొనడం కోసం ఎడమ లేదా కుడి వైపునకు స్వైప్ చేయాల్సి రావచ్చు). ఆపై, అన్ఇన్స్టాల్ చేయి లేదా నిలిపివేయి ఎంపికను నొక్కండి.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">అభ్యర్థనను పంపుతోంది...</translation> -<translation id="1732215134274276513">టాబ్లను అన్పిన్ చెయ్యండి</translation> <translation id="1733383495376208985">సమకాలీకరించిన డేటాని మీ స్వంత <ph name="BEGIN_LINK" />సమకాలీకరణ రహస్య పదబంధం<ph name="END_LINK" />తో ఎన్క్రిప్ట్ చేయండి. Google Payకి చెందిన చెల్లింపు పద్ధతులు మరియు చిరునామాలు ఇందులో ఉండవు.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> తనకు తాను అప్డేట్ అవుతూ ఉండటం సాధ్యం కాకపోవచ్చు</translation> <translation id="1736419249208073774">అన్వేషించండి</translation> @@ -552,7 +545,6 @@ <translation id="1807938677607439181">అన్ని ఫైల్లు</translation> <translation id="1809734401532861917">నా బుక్మార్క్లు, చరిత్ర, పాస్వర్డ్లు మరియు ఇతర సెట్టింగ్లను <ph name="USER_EMAIL_ADDRESS" />కి జోడించు</translation> <translation id="1810764548349082891">పరిదృశ్యం అందుబాటులో లేదు</translation> -<translation id="1812631533912615985">టాబ్లను అన్పిన్ చెయ్యండి</translation> <translation id="1813278315230285598">సేవలు</translation> <translation id="18139523105317219">EDI వేడుక పేరు</translation> <translation id="1815083418640426271">సాదా వచనం లాగా అతికించు</translation> @@ -711,7 +703,6 @@ <translation id="2065405795449409761">Chrome స్వయంచాలక పరీక్ష సాఫ్ట్వేర్ ద్వారా నియంత్రించబడుతోంది.</translation> <translation id="2070909990982335904">డాట్తో ప్రారంభమయ్యే పేర్లు సిస్టమ్ కోసం ప్రత్యేకించబడినవి. దయచేసి మరొక పేరును ఎంచుకోండి.</translation> <translation id="2071393345806050157">స్థానిక లాగ్ ఫైల్ లేదు.</translation> -<translation id="2074527029802029717">టాబ్కు పిన్ తీసివేయి</translation> <translation id="2075474481720804517">బ్యాటరీ <ph name="BATTERY_PERCENTAGE" />% ఉంది</translation> <translation id="2075959085554270910">క్లిక్ చేయడానికి నొక్కండి, నొక్కి పట్టుకుని, లాగండిని ప్రారంభించడానికి/నిలిపివేయడానికి మిమ్మల్ని అనుమతిస్తుంది</translation> <translation id="2076269580855484719">ఈ ప్లగ్ఇన్ని దాచిపెట్టు</translation> @@ -1353,7 +1344,6 @@ <translation id="3045447014237878114">ఈ సైట్ పలు ఫైల్లను ఆటోమేటిక్గా డౌన్లోడ్ చేసింది</translation> <translation id="3046910703532196514">వెబ్పేజీ, సంపూర్ణం</translation> <translation id="304747341537320566">ప్రసంగ ఇంజిన్లు</translation> -<translation id="304826556400666995">ట్యాబ్లను అన్మ్యూట్ చేయండి</translation> <translation id="3053013834507634016">సర్టిఫికెట్ కీ ఉపయోగం</translation> <translation id="3057861065630527966">మీ ఫోటోలను మరియు వీడియోలను బ్యాకప్ చేయండి</translation> <translation id="3060379269883947824">వినడానికి-ఎంచుకోండిని ప్రారంభించు</translation> @@ -2336,7 +2326,6 @@ <translation id="4628762811416793313">Linux కంటెయినర్ సెటప్ పూర్తి కాలేదు. దయచేసి మళ్లీ ప్రయత్నించండి.</translation> <translation id="4628948037717959914">ఫోటో</translation> <translation id="4631887759990505102">చిత్రకారుడు</translation> -<translation id="4632483769545853758">ట్యాబ్ని అన్మ్యూట్ చేయండి</translation> <translation id="4633003931260532286">పొడిగింపు కోసం కనీసం "<ph name="IMPORT_NAME" />" యొక్క "<ph name="IMPORT_VERSION" />" వెర్షన్ ఉండాలి, కానీ "<ph name="INSTALLED_VERSION" />" వెర్షన్ మాత్రమే ఇన్స్టాల్ చేయబడింది</translation> <translation id="4634771451598206121">మళ్ళీ సైన్ ఇన్ చెయ్యండి...</translation> <translation id="4635398712689569051">అతిథి వినియోగదారులకు <ph name="PAGE_NAME" /> అందుబాటులో లేదు.</translation> @@ -2400,7 +2389,6 @@ <translation id="4735803855089279419">ఈ పరికర ఐడెంటిఫైయర్లను గుర్తించడంలో సిస్టమ్ విఫలమైంది.</translation> <translation id="4737715515457435632">దయచేసి నెట్వర్క్కు కనెక్ట్ చేయండి</translation> <translation id="473775607612524610">అప్డేట్</translation> -<translation id="474217410105706308">ట్యాబ్ని మ్యూట్ చేయండి</translation> <translation id="4742746985488890273">అరకు పిన్ చేయండి</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />అప్లికేషన్లను ఎలా అప్డేట్ చేయాలో తెలుసుకోండి<ph name="END_LINK" /></translation> <translation id="4746351372139058112">సందేశాలు</translation> @@ -2625,7 +2613,6 @@ <translation id="5094721898978802975">సహకరిస్తున్న స్థానిక అనువర్తనాలతో కమ్యూనికేట్ చేయండి</translation> <translation id="5097002363526479830">'<ph name="NAME" />'కు నెట్వర్క్కు కనెక్ట్ చేయడానికి విఫలమైంది: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">అన్ని బుక్మార్క్లను తెరువు</translation> -<translation id="5105855035535475848">పిన్ టాబ్లు</translation> <translation id="5108967062857032718">సెట్టింగ్లు - Android అనువర్తనాలను తీసివేయి</translation> <translation id="5109044022078737958">మియా</translation> <translation id="5111692334209731439">&బుక్మార్క్ సంచాలకులు</translation> @@ -2690,7 +2677,6 @@ <translation id="520621735928254154">ప్రమాణపత్ర దిగుమతి లోపం</translation> <translation id="5209320130288484488">పరికరాలు కనుగొనబడలేదు</translation> <translation id="5209518306177824490">SHA-1 వేలిముద్ర</translation> -<translation id="5210365745912300556">ట్యాబ్ను మూసివేయి</translation> <translation id="5213481667492808996">మీ '<ph name="NAME" />' డేటా సేవ ఉపయోగించడానికి సిద్ధంగా ఉంది</translation> <translation id="5213891612754844763">ప్రాక్సీ సెట్టింగ్లను చూపు</translation> <translation id="521582610500777512">ఫోటో విస్మరించబడింది</translation> @@ -2741,7 +2727,6 @@ <translation id="5270167208902136840">మరో <ph name="NUMBER_OF_MORE_APPS" /> యాప్లను చూపు</translation> <translation id="5275352920323889391">కుక్క</translation> <translation id="5275973617553375938">Google డిస్క్ నుండి పునరుద్ధరించబడిన ఫైల్లు</translation> -<translation id="527605719918376753">ట్యాబ్ను మ్యూట్ చేయి</translation> <translation id="527605982717517565"><ph name="HOST" />పై ఎల్లప్పుడూ JavaScriptను అనుమతించు</translation> <translation id="5280426389926346830">షార్ట్కట్ని సృష్టించాలా?</translation> <translation id="528208740344463258">Android యాప్లను డౌన్లోడ్ చేసి, ఉపయోగించడం కోసం, ముందుగా మీరు ఈ అవసరమైన అప్డేట్ని ఇన్స్టాల్ చేయాలి. మీ <ph name="DEVICE_TYPE" /> అప్డేట్ అవుతున్న సమయంలో, మీరు దీనిని ఉపయోగించలేరు. ఇన్స్టాల్ చేయడం పూర్తయిన తర్వాత, మీ <ph name="DEVICE_TYPE" /> పునఃప్రారంభించబడుతుంది.</translation> @@ -2864,7 +2849,6 @@ <translation id="5449551289610225147">పాస్వర్డ్ చెల్లదు</translation> <translation id="5449588825071916739">అన్ని ట్యాబ్లను బుక్మార్క్ చేయి</translation> <translation id="5449716055534515760">&విండో మూసివెయ్యి</translation> -<translation id="5453029940327926427">టాబ్లను మూసివెయ్యి</translation> <translation id="5454166040603940656"><ph name="PROVIDER" />తో</translation> <translation id="5457113250005438886">చెల్లదు</translation> <translation id="5457459357461771897">మీ కంప్యూటర్లోని ఫోటోలు, సంగీతం మరియు ఇతర మీడియాను చదవడం మరియు తొలగించడం</translation> @@ -3329,7 +3313,6 @@ <translation id="6122875415561139701">దీనిలో వ్రాసే చర్యకు అనుమతి లేదు: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">క్రింది పొడిగింపులు ఈ పొడిగింపుపై ఆధారపడి ఉంటాయి:</translation> <translation id="6125479973208104919">దురదృష్టవశాత్తూ, మీరు మీ ఖాతాను ఈ <ph name="DEVICE_TYPE" />కి మళ్లీ జోడించాలి.</translation> -<translation id="612596694132302162">సైట్ని అన్మ్యూట్ చేయండి</translation> <translation id="6129691635767514872">ఎంచుకోబడిన డేటా- Chromeతో పాటు సమకాలీకరించిన పరికరాల నుండి తీసివేయబడింది. మీ Google ఖాతా <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" />లో ఇతర Google సేవల నుండి శోధనలు, కార్యకలాపాలు వంటి ఇతర రూపాల బ్రౌజింగ్ చరిత్రను కలిగి ఉండవచ్చు.</translation> <translation id="6129938384427316298">Netscape సర్టిఫికెట్ వ్యాఖ్య</translation> <translation id="6129953537138746214">ఖాళీ</translation> @@ -3532,7 +3515,6 @@ <translation id="6436164536244065364">వెబ్ స్టోర్లో వీక్షించండి</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - ఆడియో ప్లే చేస్తోంది</translation> <translation id="6442187272350399447">ఆసమ్</translation> -<translation id="6442697326824312960">టాబ్కు పిన్ తీసివేయి</translation> <translation id="6444070574980481588">తేదీ మరియు సమయాన్ని సెట్ చేయండి</translation> <translation id="6445450263907939268">మీరు ఈ మార్పులు అవసరం లేదని భావిస్తే, మీ మునుపటి సెట్టింగ్లను పునరుద్ధరించవచ్చు.</translation> <translation id="6447842834002726250">కుక్కీలు</translation> @@ -3735,7 +3717,6 @@ <translation id="6770664076092644100">NFC ద్వారా ధృవీకరించు</translation> <translation id="6771503742377376720">ప్రమాణపత్ర అధికారం</translation> <translation id="6777817260680419853">మళ్ళింపు బ్లాక్ చేయబడింది</translation> -<translation id="6778959797435875428">సైట్లను అన్మ్యూట్ చేయండి</translation> <translation id="677965093459947883">చాలా చిన్నవిగా</translation> <translation id="6780439250949340171">ఇతర సెట్టింగ్లను నిర్వహించండి</translation> <translation id="6781284683813954823">డూడుల్ లింక్</translation> @@ -4052,7 +4033,6 @@ <translation id="7257666756905341374">మీరు కాపీ చేసి అతికించే డేటాను చదవడం</translation> <translation id="7258697411818564379">మీ పిన్ జోడించబడింది</translation> <translation id="7262004276116528033">ఈ సైన్-ఇన్ సేవ <ph name="SAML_DOMAIN" /> ద్వారా హోస్ట్ చేయబడుతోంది</translation> -<translation id="7268365133021434339">టాబ్లను మూసివెయ్యి</translation> <translation id="7268659760406822741">అందుబాటులో ఉన్న సేవలు</translation> <translation id="7270858098575133036">MIDI పరికరాలను ప్రాప్యత చేయడానికి సిస్టమ్ విశిష్ట సందేశాలను సైట్ ఉపయోగించాలనుకున్నప్పుడు అడుగు</translation> <translation id="7272674038937250585">వివరణ ఏదీ అందించబడలేదు</translation> @@ -4242,7 +4222,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">పోగు చేయు</translation> <translation id="7576976045740938453">డెమో మోడ్ ఖాతాకు సంబంధించి ఒక సమస్య ఏర్పడింది.</translation> -<translation id="7579149537961810247">సైట్లను మ్యూట్ చేయండి</translation> <translation id="7580671184200851182">అన్ని స్పీకర్ల్లో ఒకే ఆడియోను ప్లే చేయి (మోనో ఆడియో)</translation> <translation id="7581462281756524039">క్లీన్అప్ సాధనం</translation> <translation id="7582582252461552277">ఈ నెట్వర్క్ను ప్రాధాన్యపరచు</translation> @@ -4592,7 +4571,6 @@ <translation id="8068253693380742035">సైన్ ఇన్ చేయడానికి తాకండి</translation> <translation id="8069615408251337349">Google మేఘ ముద్రణ</translation> <translation id="8071432093239591881">చిత్రం వలె ముద్రించు</translation> -<translation id="8072988827236813198">పిన్ టాబ్లు</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />పరిచయాలు, సందేశాలు మరియు ఫోటోల వంటి యాప్ సేవ్ చేసిన (డెవలపర్ సెట్టింగ్ల ఆధారంగా) ఎలాంటి డేటా అయినా యాప్ డేటాగా పరిగణించబడుతుంది.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />బ్యాకప్ డేటా మీ చిన్నారి డిస్క్ నిల్వ కోటాలో లెక్కించబడదు.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />మీరు సెట్టింగ్లలో ఈ సేవని ఆఫ్ చేయవచ్చు.<ph name="END_PARAGRAPH3" /></translation> @@ -4779,7 +4757,6 @@ <translation id="8368859634510605990">&అన్ని బుక్మార్క్లను తెరువు</translation> <translation id="8371695176452482769">ఇప్పుడు మాట్లాడండి</translation> <translation id="8372369524088641025">తప్పుడు WEP కీ</translation> -<translation id="8373553483208508744">ట్యాబ్లను మ్యూట్ చేయి</translation> <translation id="8378714024927312812">మీ సంస్థ ద్వారా నిర్వహించబడుతున్నవి</translation> <translation id="8379878387931047019">ఈ వెబ్సైట్ అభ్యర్థించిన భద్రతా కీ రకానికి ఈ పరికరం మద్దతు ఇవ్వదు</translation> <translation id="8382913212082956454">&ఇమెయిల్ చిరునామాను కాపీ చెయ్యి</translation> @@ -4887,7 +4864,6 @@ <translation id="8546930481464505581">టచ్ బార్ని అనుకూలీకరించండి</translation> <translation id="8547013269961688403">పూర్తి స్క్రీన్ మాగ్నిఫయర్ను ప్రారంభించండి</translation> <translation id="85486688517848470">ఎగువ-అడ్డు వరుసలోని కీల ప్రవర్తనను మార్చడానికి శోధన కీని నొక్కి ఉంచండి</translation> -<translation id="855081842937141170">టాబ్ను పిన్ చేయి</translation> <translation id="8551388862522347954">లైసెన్స్లు</translation> <translation id="8553342806078037065">ఇతర వ్యక్తులను నిర్వహించు</translation> <translation id="8554899698005018844">భాష లేదు</translation> @@ -5201,7 +5177,6 @@ <translation id="9038430547971207796">తర్వాతిసారి, మీ ఫోన్ మీ <ph name="DEVICE_TYPE" />ను అన్లాక్ చేస్తుంది. సెట్టింగ్లలో Smart Lockని ఆఫ్ చేయండి.</translation> <translation id="9038649477754266430">పేజీలను మరింత శీఘ్రంగా లోడ్ చేయడానికి సూచన సేవను ఉపయోగించండి</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">ట్యాబ్లను మ్యూట్ చేయండి</translation> <translation id="9040661932550800571"><ph name="ORIGIN" /> కోసం పాస్వర్డ్ను అప్డేట్ చేయాలా?</translation> <translation id="9041692268811217999">మీ యంత్రంలో స్థానిక ఫైల్లకు యాక్సెస్ని మీ నిర్వాహకులు నిలిపివేసారు</translation> <translation id="9042893549633094279">గోప్యత మరియు భద్రత</translation> @@ -5299,7 +5274,6 @@ <translation id="920045321358709304"><ph name="SEARCH_ENGINE" />ని శోధించు</translation> <translation id="9201220332032049474">స్క్రీన్ లాక్ ఎంపికలు</translation> <translation id="9203398526606335860">&ప్రొఫైలింగ్ అనుమతించబడింది</translation> -<translation id="9203478404496196495">ట్యాబ్ను అన్మ్యూట్ చేయి</translation> <translation id="9203904171912129171">ఒక పరికరాన్ని ఎంచుకోండి</translation> <translation id="9203962528777363226">ఈ పరికరం యొక్క నిర్వాహకుడు క్రొత్త వినియోగదారులను జోడించడం నిలిపివేసారు</translation> <translation id="9213073329713032541">ఇన్స్టాలేషన్ విజయవంతంగా ప్రారంభించబడింది.</translation>
diff --git a/chrome/app/resources/generated_resources_th.xtb b/chrome/app/resources/generated_resources_th.xtb index eeec872..f30dbb0 100644 --- a/chrome/app/resources/generated_resources_th.xtb +++ b/chrome/app/resources/generated_resources_th.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">กด ESCAPE เพื่อยกเลิก (รุ่นที่ไม่เป็นทางการเท่านั้น)</translation> <translation id="1093457606523402488">เครือข่ายที่แสดงตัว:</translation> <translation id="1094607894174825014">ได้รับคำขอการอ่านหรือเขียนที่มีออฟเซ็ตไม่ถูกต้องใน "<ph name="DEVICE_NAME" />"</translation> -<translation id="109758035718544977">เปิดเสียงเว็บไซต์</translation> <translation id="1097658378307015415">ก่อนที่จะลงชื่อเข้าใช้ โปรดเข้าใช้ในฐานะผู้มาเยือนเพื่อเปิดใช้งานเครือข่าย <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">แปลภาษา<ph name="LANGUAGE" />ทุกครั้ง</translation> <translation id="1108600514891325577">&หยุด</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">ใช้เว็บโดยไม่บันทึกประวัติการท่องเว็บด้วยหน้าต่างที่ไม่ระบุตัวตน</translation> <translation id="1213037489357051291">การตั้งค่าลายนิ้วมือ <ph name="NUM_FINGERPRINTS" /> รายการ</translation> <translation id="1215411991991485844">มีการเพิ่มแอปพลิเคชันที่ทำงานอยู่เบื้องหลังตัวใหม่</translation> -<translation id="1216654534877302979">ปิดเสียงเว็บไซต์</translation> <translation id="1216659994753476700">ขออภัย เราไม่สามารถเข้าถึงโปรไฟล์ของคุณ ไฟล์และข้อมูลที่จัดเก็บในอุปกรณ์นี้อาจสูญหาย<ph name="BR" /> <ph name="BR" /> คุณจะต้องตั้งค่าโปรไฟล์ของคุณอีกครั้ง<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">จัดเก็บข้อมูลในบัญชี Google ไดรฟ์</translation> <translation id="1288037062697528143">แสงตอนกลางคืนจะเปิดโดยอัตโนมัติเมื่อพระอาทิตย์ตก</translation> <translation id="1288300545283011870">คุณสมบัติของเสียงพูด</translation> -<translation id="1293177648337752319">เปิดเสียงเว็บไซต์</translation> <translation id="1293264513303784526">อุปกรณ์ USB-C (พอร์ตด้านซ้าย)</translation> <translation id="1293556467332435079">ไฟล์</translation> <translation id="1296497012903089238">ประเภทใบรับรอง</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">หน้าแรกคือหน้าแท็บใหม่</translation> <translation id="1436671784520050284">ตั้งค่าต่อ</translation> <translation id="1436784010935106834">ลบออกแล้ว</translation> -<translation id="1438632560381091872">เปิดเสียงแท็บ</translation> <translation id="1442392616396121389">ส่วนหน้าของการกำหนดเส้นทาง</translation> <translation id="144283815522798837">เลือกไว้ <ph name="NUMBER_OF_ITEMS_SELECTED" /> รายการ</translation> <translation id="1444628761356461360"><ph name="OWNER_EMAIL" /> ซึ่งเป็นเจ้าของอุปกรณ์เป็นผู้จัดการการตั้งค่านี้</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">มีการเชื่อมต่อกับแป้นพิมพ์อื่นหลังจากที่คุณป้อนรหัสผ่านครั้งล่าสุด แป้นพิมพ์นี้อาจพยายามขโมยการกดแป้นพิมพ์ของคุณ</translation> <translation id="1567750922576943685">การยืนยันตัวตนจะช่วยปกป้องข้อมูลส่วนบุคคล</translation> <translation id="1567993339577891801">คอนโซล JavaScript</translation> -<translation id="1568067597247500137">ปิดเสียงเว็บไซต์</translation> <translation id="1568323446248056064">เปิดการตั้งค่าอุปกรณ์แสดงผล</translation> <translation id="1572266655485775982">เปิดใช้ Wi-Fi</translation> <translation id="1572585716423026576">ตั้งเป็นวอลเปเปอร์</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">ลายเซ็น X9.62 ECDSA ที่มี SHA-1</translation> <translation id="1644574205037202324">ประวัติการเข้าชม</translation> <translation id="1645516838734033527">Smart Lock จำเป็นต้องใช้การล็อกหน้าจอในโทรศัพท์เพื่อรักษา <ph name="DEVICE_TYPE" /> ของคุณให้ปลอดภัย</translation> -<translation id="1646102270785326155">เมื่อผู้ใช้นี้ถูกนำออก ระบบจะลบไฟล์และข้อมูลในเครื่องทั้งหมดที่เกี่ยวข้องกับผู้ใช้ออกโดยถาวร $1 ยังลงชื่อเข้าใช้ได้ในภายหลัง</translation> <translation id="1646982517418478057">โปรดป้อนรหัสผ่านเพื่อเข้ารหัสใบรับรองนี้</translation> <translation id="164814987133974965">ผู้ใช้ภายใต้การดูแลสามารถสำรวจเว็บโดยใช้คำแนะนำของคุณ ในฐานะที่เป็นผู้จัดการของผู้ใช้ภายใต้การดูแล คุณสามารถ <ph name="BEGIN_BOLD" />อนุญาตหรือห้าม<ph name="END_BOLD" />บางเว็บไซต์ @@ -499,7 +493,6 @@ <translation id="1729533290416704613">อีกทั้งยังควบคุมหน้าที่จะแสดงเมื่อคุณทำการค้นหาจากแถบอเนกประสงค์ด้วย</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />หากต้องการนำแอปออก ให้ไปที่การตั้งค่า > Google Play Store > จัดการค่ากำหนด Android > ตัวจัดการแอปหรือแอปพลิเคชัน แล้วแตะแอปที่คุณต้องการถอนการติดตั้ง (อาจต้องเลื่อนไปทางขวาหรือทางซ้ายเพื่อค้นหาแอป) และแตะถอนการติดตั้ง หรือปิดใช้<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">กำลังส่งคำขอ...</translation> -<translation id="1732215134274276513">เลิกตรึงแท็บ</translation> <translation id="1733383495376208985">เข้ารหัสลับข้อมูลที่ซิงค์ด้วย<ph name="BEGIN_LINK" />รหัสผ่านการซิงค์<ph name="END_LINK" />ของคุณเอง ข้อมูลนี้ไม่รวมถึงวิธีการชำระเงินและที่อยู่จาก Google Pay</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> อาจอัปเดตตัวเองตลอดเวลาไม่ได้</translation> <translation id="1736419249208073774">สำรวจ</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">ไฟล์ทั้งหมด</translation> <translation id="1809734401532861917">เพิ่มบุ๊กมาร์ก ประวัติการเข้าชม รหัสผ่าน และการตั้งค่าอื่นๆ ของฉันไปยัง <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">ไม่มีพรีวิว</translation> -<translation id="1812631533912615985">เลิกตรึงแท็บ</translation> <translation id="1813278315230285598">บริการ</translation> <translation id="18139523105317219">ชื่อหน่วย EDI</translation> <translation id="1815083418640426271">วางเป็นข้อความธรรมดา</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">ซอฟต์แวร์ทดสอบอัตโนมัติกำลังควบคุม Chrome อยู่</translation> <translation id="2070909990982335904">ชื่อที่ขึ้นต้นด้วยจุดสงวนไว้สำหรับระบบ โปรดเลือกชื่ออื่น</translation> <translation id="2071393345806050157">ไม่มีไฟล์บันทึกในเครื่อง</translation> -<translation id="2074527029802029717">ยกเลิกการตรึงแท็บ</translation> <translation id="2075474481720804517">แบตเตอรี่ <ph name="BATTERY_PERCENTAGE" />%</translation> <translation id="2075959085554270910">ช่วยให้คุณเปิด/ปิดใช้การแตะเพื่อคลิกและการแตะแล้วลากได้</translation> <translation id="2076269580855484719">ซ่อนปลั๊กอินนี้</translation> @@ -1357,7 +1348,6 @@ <translation id="3045447014237878114">เว็บไซต์นี้มีการดาวน์โหลดไฟล์หลายไฟล์โดยอัตโนมัติ</translation> <translation id="3046910703532196514">หน้าเว็บ ทั้งหมด</translation> <translation id="304747341537320566">เครื่องมืออ่านออกเสียง</translation> -<translation id="304826556400666995">เปิดเสียงแท็บ</translation> <translation id="3053013834507634016">การใช้คีย์ใบรับรอง </translation> <translation id="3057861065630527966">สำรองรูปภาพและวิดีโอ</translation> <translation id="3060379269883947824">เปิดใช้การเลือกเพื่อให้อ่าน</translation> @@ -2343,7 +2333,6 @@ <translation id="4628762811416793313">ยังสร้างคอนเทนเนอร์ Linux ไม่สมบูรณ์ โปรดลองอีกครั้ง</translation> <translation id="4628948037717959914">รูปภาพ</translation> <translation id="4631887759990505102">ศิลปิน</translation> -<translation id="4632483769545853758">เปิดเสียงแท็บ</translation> <translation id="4633003931260532286">ส่วนขยายต้องใช้ "<ph name="IMPORT_NAME" />" เวอร์ชัน "<ph name="IMPORT_VERSION" />" เป็นอย่างน้อย แต่ที่ติดตั้งอยู่เป็นเวอร์ชัน "<ph name="INSTALLED_VERSION" />"</translation> <translation id="4634771451598206121">ลงชื่อเข้าใช้อีกครั้ง...</translation> <translation id="4635398712689569051">ผู้ใช้ที่เป็นผู้มาเยือนไม่สามารถใช้ <ph name="PAGE_NAME" /></translation> @@ -2408,7 +2397,6 @@ <translation id="4736292055110123391">ซิงค์บุ๊กมาร์ก รหัสผ่าน ประวัติการเข้าชม และอื่นๆ ในอุปกรณ์ทุกเครื่อง</translation> <translation id="4737715515457435632">โปรดเชื่อมต่อเครือข่าย</translation> <translation id="473775607612524610">อัปเดต</translation> -<translation id="474217410105706308">ปิดเสียงแท็บ</translation> <translation id="4742746985488890273">ตรึงที่ชั้นวาง</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />ดูวิธีอัปเดตแอปพลิเคชัน<ph name="END_LINK" /></translation> <translation id="4746351372139058112">ข้อความ</translation> @@ -2633,7 +2621,6 @@ <translation id="5094721898978802975">สื่อสารกับแอปพลิเคชันการประสานงานที่มาพร้อมเครื่อง</translation> <translation id="5097002363526479830">ไม่สามารถเชื่อมต่อเครือข่าย "<ph name="NAME" />": <ph name="DETAILS" /></translation> <translation id="5101042277149003567">เปิดบุ๊กมาร์กทั้งหมด</translation> -<translation id="5105855035535475848">ตรึงแท็บ</translation> <translation id="5108967062857032718">การตั้งค่า - นำแอป Android ออก</translation> <translation id="5109044022078737958">มีอา</translation> <translation id="5111692334209731439">&ตัวจัดการบุ๊กมาร์ก</translation> @@ -2698,7 +2685,6 @@ <translation id="520621735928254154">เกิดข้อผิดพลาดในการนำเข้าใบรับรอง</translation> <translation id="5209320130288484488">ไม่พบอุปกรณ์</translation> <translation id="5209518306177824490">ลายนิ้วมือ SHA-1</translation> -<translation id="5210365745912300556">ปิดแท็บ</translation> <translation id="5213481667492808996">บริการอินเทอร์เน็ต "<ph name="NAME" />" พร้อมใช้งานแล้ว</translation> <translation id="5213891612754844763">แสดงการตั้งค่าพร็อกซี</translation> <translation id="521582610500777512">รูปภาพถูกยกเลิกแล้ว</translation> @@ -2750,7 +2736,6 @@ <translation id="5272654297705279635">การตั้งค่าที่กำหนดเอง</translation> <translation id="5275352920323889391">สุนัข</translation> <translation id="5275973617553375938">ไฟล์ที่กู้คืนจาก Google ไดรฟ์</translation> -<translation id="527605719918376753">ปิดเสียงแท็บ</translation> <translation id="527605982717517565">อนุญาตให้เรียกใช้ JavaScript บน <ph name="HOST" /> เสมอ</translation> <translation id="5280426389926346830">สร้างทางลัดไหม</translation> <translation id="528208740344463258">คุณต้องติดตั้งอัปเดตที่จำเป็นนี้ก่อนจึงจะดาวน์โหลดและใช้แอป Android ได้ และจะใช้ <ph name="DEVICE_TYPE" /> ขณะกำลังอัปเดตไม่ได้ <ph name="DEVICE_TYPE" /> จะรีสตาร์ทหลังการติดตั้งเสร็จสมบูรณ์</translation> @@ -2873,7 +2858,6 @@ <translation id="5449551289610225147">รหัสผ่านไม่ถูกต้อง</translation> <translation id="5449588825071916739">บุ๊กมาร์กแท็บทั้งหมด</translation> <translation id="5449716055534515760">ปิดหน้าต่&าง</translation> -<translation id="5453029940327926427">ปิดแท็บ</translation> <translation id="5454166040603940656">กับ <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">ไม่ถูกต้อง</translation> <translation id="5457459357461771897">อ่านและลบรูปภาพ เพลง และสื่ออื่นๆ จากคอมพิวเตอร์ของคุณ</translation> @@ -3338,7 +3322,6 @@ <translation id="6122875415561139701">ไม่อนุญาตให้เขียนใน "<ph name="DEVICE_NAME" />"</translation> <translation id="6124650939968185064">ส่วนขยายต่อไปนี้ต้องพึ่งพาส่วนขยายนี้:</translation> <translation id="6125479973208104919">ขออภัย คุณจะต้องเพิ่มบัญชีของคุณลงใน <ph name="DEVICE_TYPE" /> นี้อีกครั้ง</translation> -<translation id="612596694132302162">เปิดเสียงเว็บไซต์</translation> <translation id="6129691635767514872">นำข้อมูลที่เลือกออกจาก Chrome และอุปกรณ์ที่ซิงค์แล้ว บัญชี Google ของคุณอาจมีประวัติการท่องเว็บในรูปแบบอื่น เช่น การค้นหาและกิจกรรมจากบริการอื่นๆ ของ Google ที่ <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> <translation id="6129938384427316298">ความคิดเห็นเกี่ยวกับใบรับรองของ Netscape</translation> <translation id="6129953537138746214">ช่องว่าง</translation> @@ -3541,7 +3524,6 @@ <translation id="6436164536244065364">ดูในเว็บสโตร์</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - เล่นอัตโนมัติ</translation> <translation id="6442187272350399447">ออซั่ม</translation> -<translation id="6442697326824312960">ยกเลิกการตรึงแท็บ</translation> <translation id="6444070574980481588">ตั้งวันที่และเวลา</translation> <translation id="6445450263907939268">หากคุณไม่ต้องการการเปลี่ยนแปลงเหล่านี้ คุณสามารถกู้คืนการตั้งค่าก่อนหน้าได้</translation> <translation id="6447842834002726250">คุกกี้</translation> @@ -3744,7 +3726,6 @@ <translation id="6770664076092644100">ยืนยันผ่าน NFC</translation> <translation id="6771503742377376720">เป็นผู้ออกใบรับรอง</translation> <translation id="6777817260680419853">การเปลี่ยนเส้นทางถูกบล็อก</translation> -<translation id="6778959797435875428">เปิดเสียงเว็บไซต์</translation> <translation id="677965093459947883">เล็กมาก</translation> <translation id="6780439250949340171">จัดการการตั้งค่าอื่นๆ</translation> <translation id="6781284683813954823">ลิงก์ของ Doodle</translation> @@ -4061,7 +4042,6 @@ <translation id="7257666756905341374">อ่านข้อมูลที่คุณคัดลอกและวาง</translation> <translation id="7258697411818564379">เพิ่ม PIN ของคุณแล้ว</translation> <translation id="7262004276116528033">บริการลงชื่อเข้าใช้นี้โฮสต์โดย <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">ปิดแท็บ</translation> <translation id="7268659760406822741">บริการที่มี</translation> <translation id="7270858098575133036">ถามเมื่อเว็บไซต์ต้องการใช้ข้อความเฉพาะของระบบในการเข้าถึงอุปกรณ์ MIDI</translation> <translation id="7272674038937250585">ไม่มีคำอธิบาย</translation> @@ -4251,7 +4231,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">เรียง</translation> <translation id="7576976045740938453">เกิดปัญหาเกี่ยวกับบัญชีโหมดสาธิต</translation> -<translation id="7579149537961810247">ปิดเสียงเว็บไซต์</translation> <translation id="7580671184200851182">เล่นเสียงเหมือนกันผ่านลำโพงทุกตัว (เสียงโมโน)</translation> <translation id="7581462281756524039">เครื่องมือทำความสะอาด</translation> <translation id="7582582252461552277">ต้องการใช้เครือข่ายนี้</translation> @@ -4605,7 +4584,6 @@ <translation id="8068253693380742035">แตะเพื่อลงชื่อเข้าใช้</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">พิมพ์เป็นรูปภาพ</translation> -<translation id="8072988827236813198">ตรึงแท็บ</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />ข้อมูลแอปอาจเป็นข้อมูลใดก็ตามที่แอปบันทึกไว้ (โดยอิงตามการตั้งค่าของนักพัฒนาซอฟต์แวร์) ซึ่งรวมถึงข้อมูลอย่างเช่น รายชื่อติดต่อ ข้อความ และรูปภาพ<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />ข้อมูลสำรองจะไม่นับรวมในโควต้าพื้นที่เก็บข้อมูล Google ไดรฟ์ของบุตรหลาน<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />คุณปิดบริการนี้ได้ในการตั้งค่า<ph name="END_PARAGRAPH3" /></translation> @@ -4791,7 +4769,6 @@ <translation id="8368859634510605990">&เปิดบุ๊กมาร์กทั้งหมด</translation> <translation id="8371695176452482769">เชิญพูดเลย</translation> <translation id="8372369524088641025">คีย์ WEP ไม่ถูกต้อง</translation> -<translation id="8373553483208508744">ปิดเสียงแท็บ</translation> <translation id="8378714024927312812">จัดการโดยองค์กร</translation> <translation id="8379878387931047019">อุปกรณ์นี้ไม่รองรับประเภทคีย์ความปลอดภัยที่เว็บไซต์นี้กำหนดไว้</translation> <translation id="8382913212082956454">คัดลอก&ที่อยู่อีเมล</translation> @@ -4899,7 +4876,6 @@ <translation id="8546930481464505581">ปรับแต่ง Touch Bar</translation> <translation id="8547013269961688403">เปิดใช้แว่นขยายทั้งหน้าจอ</translation> <translation id="85486688517848470">กดแป้น "ค้นหา" ค้างไว้เพื่อเปลี่ยนการทำงานของแป้นแถวบนสุด</translation> -<translation id="855081842937141170">ตรึงแท็บ</translation> <translation id="8551388862522347954">ใบอนุญาต</translation> <translation id="8553342806078037065">จัดการบุคคลอื่นๆ</translation> <translation id="8554899698005018844">ไม่มีภาษา</translation> @@ -5214,7 +5190,6 @@ <translation id="9038430547971207796">โทรศัพท์จะปลดล็อก <ph name="DEVICE_TYPE" /> ของคุณในครั้งถัดไป คุณสามารถปิด Smart Lock ได้ใน "การตั้งค่า"</translation> <translation id="9038649477754266430">ใช้บริการการคาดคะเนเพื่อโหลดหน้าได้เร็วขึ้น</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">ปิดเสียงแท็บ</translation> <translation id="9040661932550800571">อัปเดตรหัสผ่านสำหรับ <ph name="ORIGIN" /> ไหม</translation> <translation id="9041692268811217999">ผู้ดูแลระบบปิดการเข้าถึงไฟล์ในเครื่องของคุณ</translation> <translation id="9042893549633094279">ข้อมูลส่วนบุคคลและความปลอดภัย</translation> @@ -5312,7 +5287,6 @@ <translation id="920045321358709304">ค้นหา <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">ตัวเลือกการล็อกหน้าจอ</translation> <translation id="9203398526606335860">&เปิดใช้งานการทำแฟ้มประวัติ</translation> -<translation id="9203478404496196495">เปิดเสียงแท็บ</translation> <translation id="9203904171912129171">เลือกอุปกรณ์</translation> <translation id="9203962528777363226">ผู้ดูแลระบบของอุปกรณ์นี้ปิดการใช้งานไม่ให้เพิ่มผู้ใช้ใหม่เข้าไป</translation> <translation id="9213073329713032541">เริ่มการติดตั้งสำเร็จแล้ว</translation>
diff --git a/chrome/app/resources/generated_resources_tr.xtb b/chrome/app/resources/generated_resources_tr.xtb index ce9b3ef3..3e028aa 100644 --- a/chrome/app/resources/generated_resources_tr.xtb +++ b/chrome/app/resources/generated_resources_tr.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Atlamak için ESCAPE tuşuna basın (Yalnızca resmi olmayan sürümler).</translation> <translation id="1093457606523402488">Görünür Ağlar:</translation> <translation id="1094607894174825014">Şu cihazda geçersiz bir ofset değeriyle okuma veya yazma işlemi istendi: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">Sitelerin Sesini Aç</translation> <translation id="1097658378307015415">Oturum açmadan önce <ph name="NETWORK_ID" /> ağını etkinleştirmek için lütfen Misafir olarak giriş yapın</translation> <translation id="1103523840287552314"><ph name="LANGUAGE" /> dilini daima çevir</translation> <translation id="1108600514891325577">D&urdur</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Gizli pencere sayesinde göz atma geçmişinizi kaydetmeden web'i kullanın</translation> <translation id="1213037489357051291"><ph name="NUM_FINGERPRINTS" /> parmak izi ayarlandı</translation> <translation id="1215411991991485844">Yeni arka plan uygulaması eklendi</translation> -<translation id="1216654534877302979">Sitelerin sesini kapat</translation> <translation id="1216659994753476700">Maalesef profilinize erişemiyoruz. Bu cihazda depolanan dosyalar ve veriler kaybolmuş olabilir.<ph name="BR" /> <ph name="BR" /> Profilinizi tekrar ayarlamanız gerekecek.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Verileri Google Drive hesabınızda depolama</translation> <translation id="1288037062697528143">Gece Işığı güneş battığında otomatik olarak açılır</translation> <translation id="1288300545283011870">Konuşma Özellikleri</translation> -<translation id="1293177648337752319">Sitenin Sesini Aç</translation> <translation id="1293264513303784526">USB-C cihaz (sol bağlantı noktası)</translation> <translation id="1293556467332435079">Dosyalar</translation> <translation id="1296497012903089238">Sertifika Türü</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Ana sayfa Yeni Sekme sayfasıdır</translation> <translation id="1436671784520050284">Kuruluma devam et</translation> <translation id="1436784010935106834">Kaldırıldı</translation> -<translation id="1438632560381091872">Sekmelerin sesini aç</translation> <translation id="1442392616396121389">Yönlendirme öneki</translation> <translation id="144283815522798837"><ph name="NUMBER_OF_ITEMS_SELECTED" /> öğe seçildi</translation> <translation id="1444628761356461360">Bu ayar, cihaz sahibi <ph name="OWNER_EMAIL" /> tarafından yönetiliyor.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Şifrenizi son girdiğinizden bu yana farklı bir klavye bağlandı. Bu klavye, tuş vuruşlarınızı çalmaya çalışıyor olabilir.</translation> <translation id="1567750922576943685">Kimliğinizin doğrulanması kişisel bilgilerinizin korunmasına yardımcı olur</translation> <translation id="1567993339577891801">JavaScript Konsolu</translation> -<translation id="1568067597247500137">Sitenin sesini kapat</translation> <translation id="1568323446248056064">Ekran cihaz ayarlarını aç</translation> <translation id="1572266655485775982">Kablosuz bağlantıyı etkinleştir</translation> <translation id="1572585716423026576">Duvar kağıdı yap</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">SHA-1 ile X9.62 ECDSA İmzası</translation> <translation id="1644574205037202324">Geçmiş</translation> <translation id="1645516838734033527">Smart Lock, <ph name="DEVICE_TYPE" /> cihazınızın güvenliğini sağlamak için telefonunuzda bir ekran kilidinin bulunmasını gerektirir.</translation> -<translation id="1646102270785326155">Bu kullanıcıyla ilişkilendirilen tüm dosyalar ve yerel veriler, bu kullanıcı kaldırıldıktan sonra kalıcı olarak silinecektir. $2 daha sonra oturum açmaya devam edebilir.</translation> <translation id="1646982517418478057">Lütfen bu sertifika dosyasını şifrelemek için bir şifre girin</translation> <translation id="164814987133974965">Denetlenen bir kullanıcı sizin rehberliğinizle web'de arama yapabilir. Denetlenen bir kullanıcının yöneticisi olarak, belirli sitelere <ph name="BEGIN_BOLD" />izin verebilir veya engelleyebilir<ph name="END_BOLD" />, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Ayrıca, Çok Amaçlı Adres Çubuğu'ndan arama yaptığınızda gösterilecek sayfayı da denetler.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Uygulamaları kaldırmak için Ayarlar > Google Play Store > Android tercihlerini yönet > Uygulamalar veya Uygulama yöneticisi'ne gidin. Daha sonra, yüklemesini kaldırmak istediğiniz uygulamaya dokunun (uygulamayı bulmak için sağa veya sola doğru hızlıca kaydırmanız gerekebilir). Ardından, Yüklemeyi Kaldır veya Devre Dışı Bırak'a dokunun.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">İstek gönderiliyor...</translation> -<translation id="1732215134274276513">Sekmelerin Sabitlemesini Kaldır</translation> <translation id="1733383495376208985">Senkronize edilen verileri kendi <ph name="BEGIN_LINK" />senkronizasyon parolanızla<ph name="END_LINK" /> şifreleyin. Google Pay'deki adresler ve ödeme yöntemleri bu kapsamda değildir.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> kendisini güncel tutamayabilir</translation> <translation id="1736419249208073774">Keşfet</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Tüm dosyalar</translation> <translation id="1809734401532861917">Yer işaretlerimi, geçmişimi ve diğer ayarlarımı <ph name="USER_EMAIL_ADDRESS" /> adresine ekle</translation> <translation id="1810764548349082891">Önizleme yok</translation> -<translation id="1812631533912615985">Sekmelerin sabitlemesini kaldır</translation> <translation id="1813278315230285598">Hizmetler</translation> <translation id="18139523105317219">EDI Grup Adı</translation> <translation id="1815083418640426271">Düz Metin Olarak Yapıştır</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chrome otomatik test yazılımı tarafından kontrol ediliyor.</translation> <translation id="2070909990982335904">Nokta ile başlayan adlar sistem için ayrılmıştır. Lütfen başka bir ad seçin.</translation> <translation id="2071393345806050157">Yerel günlük dosyası yok.</translation> -<translation id="2074527029802029717">Sekmeyi ayır</translation> <translation id="2075474481720804517">%<ph name="BATTERY_PERCENTAGE" /> Pil</translation> <translation id="2075959085554270910">Dokunarak tıklama ve dokunarak sürükleme işlevlerini etkinleştirmenize/devre dışı bırakmanıza izin verir</translation> <translation id="2076269580855484719">Bu eklentiyi gizle</translation> @@ -1352,7 +1343,6 @@ <translation id="3045447014237878114">Bu site birden fazla dosyayı otomatik olarak indirdi</translation> <translation id="3046910703532196514">Web Sayfası, Tamamı</translation> <translation id="304747341537320566">Konuşma Motorları</translation> -<translation id="304826556400666995">Sekmelerin Sesini Aç</translation> <translation id="3053013834507634016">Sertifika Anahtarı Kullanımı</translation> <translation id="3057861065630527966">Fotoğraflarınızı ve videolarınızı yedekleyin</translation> <translation id="3060379269883947824">Seç ve Dinle'yi etkinleştir</translation> @@ -2335,7 +2325,6 @@ <translation id="4628762811416793313">Linux kapsayıcısı kurulumu tamamlanmadı. Lütfen tekrar deneyin.</translation> <translation id="4628948037717959914">Fotoğraf</translation> <translation id="4631887759990505102">Sanatçı</translation> -<translation id="4632483769545853758">Sekmenin Sesini Aç</translation> <translation id="4633003931260532286">Uzantı en az "<ph name="IMPORT_NAME" />" "<ph name="IMPORT_VERSION" />" sürümünü gerektiriyor ancak sadece "<ph name="INSTALLED_VERSION" />" sürümü yüklü</translation> <translation id="4634771451598206121">Tekrar oturum açın...</translation> <translation id="4635398712689569051"><ph name="PAGE_NAME" />, Davetli kullanıcılar için geçerli değildir.</translation> @@ -2399,7 +2388,6 @@ <translation id="4735803855089279419">Sistem, bu cihaz için cihaz tanıtıcılarını belirleyemedi.</translation> <translation id="4737715515457435632">Lütfen bir ağa bağlanın</translation> <translation id="473775607612524610">Güncelle</translation> -<translation id="474217410105706308">Sekmenin Sesini Kapat</translation> <translation id="4742746985488890273">Rafa sabitle</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Uygulamaların nasıl güncelleneceğini öğrenin<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Mesajlar</translation> @@ -2624,7 +2612,6 @@ <translation id="5094721898978802975">İşbirliği yapan yerel uygulamalarla iletişim kurma</translation> <translation id="5097002363526479830">'<ph name="NAME" />' ağına bağlanamadı: <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Tüm yer işaretlerini aç</translation> -<translation id="5105855035535475848">Sabit sekmeler</translation> <translation id="5108967062857032718">Ayarlar - Android uygulamalarını kaldır</translation> <translation id="5109044022078737958">Maya</translation> <translation id="5111692334209731439">&Yer İşareti Yöneticisi</translation> @@ -2689,7 +2676,6 @@ <translation id="520621735928254154">Sertifika İçe Aktarma Hatası</translation> <translation id="5209320130288484488">Cihaz bulunamadı</translation> <translation id="5209518306177824490">SHA-1 Parmak İzi</translation> -<translation id="5210365745912300556">Sekmeyi kapat</translation> <translation id="5213481667492808996">"<ph name="NAME" />" veri hizmetiniz kullanıma hazır</translation> <translation id="5213891612754844763">Proxy ayarlarını göster</translation> <translation id="521582610500777512">Fotoğraf silindi</translation> @@ -2740,7 +2726,6 @@ <translation id="5270167208902136840"><ph name="NUMBER_OF_MORE_APPS" /> uygulama daha göster</translation> <translation id="5275352920323889391">Köpek</translation> <translation id="5275973617553375938">Dosyalar Google Drive'dan geri yüklendi</translation> -<translation id="527605719918376753">Sekmenin sesini kapat</translation> <translation id="527605982717517565"><ph name="HOST" /> sitesinde JavaScript'e her zaman izin ver</translation> <translation id="5280426389926346830">Kısayol Oluşturulsun mu?</translation> <translation id="528208740344463258">Android uygulamalarını indirmek ve kullanmak için öncelikle bu gerekli güncellemeyi yüklemeniz gerekir. Güncelleme işlemi sırasında <ph name="DEVICE_TYPE" /> cihazınızı kullanamazsınız. Yükleme tamamlandıktan sonra <ph name="DEVICE_TYPE" /> cihazınız yeniden başlatılır.</translation> @@ -2863,7 +2848,6 @@ <translation id="5449551289610225147">Geçersiz şifre</translation> <translation id="5449588825071916739">Tüm Sekmelere Yer İşareti Koy</translation> <translation id="5449716055534515760">Pencereyi &Kapat</translation> -<translation id="5453029940327926427">Sekmeleri kapat</translation> <translation id="5454166040603940656"><ph name="PROVIDER" /> ile</translation> <translation id="5457113250005438886">Geçersiz</translation> <translation id="5457459357461771897">Bilgisayarınızdaki fotoğrafları, müzikleri ve diğer medyaları okuma ve silme</translation> @@ -3329,7 +3313,6 @@ <translation id="6122875415561139701">Şu cihazda yazma işlemine izin verilmiyor: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">Aşağıdaki uzantılar bu uzantıya bağımlıdır:</translation> <translation id="6125479973208104919">Ne yazık ki hesabınızı bu <ph name="DEVICE_TYPE" /> cihaza tekrar eklemeniz gerekecek.</translation> -<translation id="612596694132302162">Sitenin sesini aç</translation> <translation id="6129691635767514872">Seçilen veriler Chrome'dan ve senkronize edilen cihazlardan kaldırıldı. <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> adresinde, diğer Google hizmetlerinden yapılan aramalar ve etkinlikler gibi Google Hesabınızla ilişkili başka biçimlerde tarama geçmişi bulunabilir.</translation> <translation id="6129938384427316298">Netscape Sertifikası Yorumu</translation> <translation id="6129953537138746214">Boşluk</translation> @@ -3532,7 +3515,6 @@ <translation id="6436164536244065364">Web Mağazasında Görüntüle</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - Ses çalıyor</translation> <translation id="6442187272350399447">Harika!</translation> -<translation id="6442697326824312960">Sekmeyi Ayır</translation> <translation id="6444070574980481588">Tarihi ve saati ayarlayın</translation> <translation id="6445450263907939268">Bu değişiklikleri istemiyorsanız önceki ayarlarınızı geri yükleyebilirsiniz.</translation> <translation id="6447842834002726250">Çerezler</translation> @@ -3735,7 +3717,6 @@ <translation id="6770664076092644100">NFC kullanarak doğrula</translation> <translation id="6771503742377376720">Sertifika Yetkilisidir</translation> <translation id="6777817260680419853">Yönlendirme engellendi</translation> -<translation id="6778959797435875428">Sitelerin sesini aç</translation> <translation id="677965093459947883">Çok küçük</translation> <translation id="6780439250949340171">diğer ayarları yönetin</translation> <translation id="6781284683813954823">Doodle Bağlantısı</translation> @@ -4052,7 +4033,6 @@ <translation id="7257666756905341374">Kopyaladığınız ve yapıştırdığınız verileri okuma</translation> <translation id="7258697411818564379">PIN'iniz eklendi</translation> <translation id="7262004276116528033">Bu oturum açma hizmeti, <ph name="SAML_DOMAIN" /> tarafından barındırılıyor.</translation> -<translation id="7268365133021434339">Sekmeleri Kapat</translation> <translation id="7268659760406822741">Kullanılabilir hizmetler</translation> <translation id="7270858098575133036">Bir site MIDI cihazlarına erişmek için sisteme özgü mesajları kullanmak istediğinde sor</translation> <translation id="7272674038937250585">Açıklama sağlanmadı</translation> @@ -4242,7 +4222,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">Harmanla</translation> <translation id="7576976045740938453">Demo modu hesabıyla ilgili bir sorun oluştu.</translation> -<translation id="7579149537961810247">Sitelerin Sesini Kapat</translation> <translation id="7580671184200851182">Tüm hoparlörlerden aynı sesi çal (mono ses)</translation> <translation id="7581462281756524039">Temizleme aracı</translation> <translation id="7582582252461552277">Bu ağı tercih et</translation> @@ -4595,7 +4574,6 @@ <translation id="8068253693380742035">Oturum açmak için dokunun</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Resim olarak yazdır</translation> -<translation id="8072988827236813198">Sekmeleri Sabitle</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Uygulama verileri, bir uygulamanın kaydettiği her tür veri olabilir (geliştirici ayarlarına bağlıdır) ve bu veriler arasında kişiler, iletiler ve fotoğraflar gibi veriler de bulunabilir.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Yedeklenen veriler çocuğunuzun Drive Depolama Alanı kotasından düşülmez.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Bu hizmeti Ayarlar'dan kapatabilirsiniz.<ph name="END_PARAGRAPH3" /></translation> @@ -4781,7 +4759,6 @@ <translation id="8368859634510605990">&Tüm yer işaretlerini aç</translation> <translation id="8371695176452482769">Şimdi konuşun</translation> <translation id="8372369524088641025">Hatalı WEP anahtarı</translation> -<translation id="8373553483208508744">Sekmelerin sesini kapat</translation> <translation id="8378714024927312812">Kuruluşunuz tarafından yönetiliyor</translation> <translation id="8379878387931047019">Bu cihaz, bu web sitesi tarafından istenen türde güvenlik anahtarını desteklemiyor</translation> <translation id="8382913212082956454">E-posta &adresini kopyala</translation> @@ -4889,7 +4866,6 @@ <translation id="8546930481464505581">Dokunmatik Çubuğu Özelleştir</translation> <translation id="8547013269961688403">Tam ekran büyüteci etkinleştir</translation> <translation id="85486688517848470">Üst satırdaki tuşların davranışını değiştirmek için Arama tuşunu basılı tutun</translation> -<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> @@ -5203,7 +5179,6 @@ <translation id="9038430547971207796">Bir dahaki sefere telefonunuzu kullanarak <ph name="DEVICE_TYPE" /> cihazınızın kilidini açabilirsiniz. Ayarlar'dan Smart Lock'u kapatın.</translation> <translation id="9038649477754266430">Sayfaları daha hızlı yüklemek için bir tahmin hizmeti kullan</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Sekmelerin Sesini Kapat</translation> <translation id="9040661932550800571"><ph name="ORIGIN" /> için şifre güncellensin mi?</translation> <translation id="9041692268811217999">Makinenizde yerel dosyalara erişim, yöneticiniz tarafından devre dışı bırakılmış durumda</translation> <translation id="9042893549633094279">Gizlilik ve güvenlik</translation> @@ -5301,7 +5276,6 @@ <translation id="920045321358709304"><ph name="SEARCH_ENGINE" /> üzerinde ara</translation> <translation id="9201220332032049474">Ekran kilidi seçenekleri</translation> <translation id="9203398526606335860">&Profil oluşturma etkin</translation> -<translation id="9203478404496196495">Sekmenin sesini aç</translation> <translation id="9203904171912129171">Cihaz seçin</translation> <translation id="9203962528777363226">Bu cihazın yöneticisi yeni kullanıcıların eklenmesini devre dışı bıraktı</translation> <translation id="9213073329713032541">Yükleme işlemi başarıyla başlatıldı.</translation>
diff --git a/chrome/app/resources/generated_resources_uk.xtb b/chrome/app/resources/generated_resources_uk.xtb index 47c0c3c8..0dfb6bf 100644 --- a/chrome/app/resources/generated_resources_uk.xtb +++ b/chrome/app/resources/generated_resources_uk.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Натисніть ESCAPE, щоб пропустити (лише в неофіційних версіях складання).</translation> <translation id="1093457606523402488">Видимі мережі:</translation> <translation id="1094607894174825014">Запит на операцію перегляду або внесення змін надіслано з недійсним зміщенням на пристрої <ph name="DEVICE_NAME" />.</translation> -<translation id="109758035718544977">Увімкнути звук на сайтах</translation> <translation id="1097658378307015415">Перш ніж увійти, розпочніть сеанс у режимі гостя, щоб активувати мережу <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Завжди перекладати з такої мови: <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Зупинити</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Відкрийте анонімне вікно й користуйтесь Інтернетом, не зберігаючи історію веб-перегляду</translation> <translation id="1213037489357051291">Налаштовано відбитків пальців: <ph name="NUM_FINGERPRINTS" /></translation> <translation id="1215411991991485844">Додано нову фонову програму</translation> -<translation id="1216654534877302979">Вимкнути звук на сайтах</translation> <translation id="1216659994753476700">На жаль, нам не вдалось отримати доступ до вашого профілю. Можливо, файли й дані, збережені на цьому пристрої, утрачено.<ph name="BR" /> <ph name="BR" /> Вам потрібно знову налаштувати свій профіль.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Зберігати дані в обліковому записі Google Диска</translation> <translation id="1288037062697528143">Нічний режим увімкнеться автоматично після заходу сонця</translation> <translation id="1288300545283011870">Властивості мовлення</translation> -<translation id="1293177648337752319">Увімкнути звук на сайті</translation> <translation id="1293264513303784526">Пристрій із портом USB типу C (ліворуч)</translation> <translation id="1293556467332435079">Файли</translation> <translation id="1296497012903089238">Тип сертифіката</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Домашня сторінка – це сторінка нової вкладки</translation> <translation id="1436671784520050284">Продовжити налаштування</translation> <translation id="1436784010935106834">Видалено</translation> -<translation id="1438632560381091872">Увімкнути звук на вкладках</translation> <translation id="1442392616396121389">Префікс маршрутизації</translation> <translation id="144283815522798837">Вибрано <ph name="NUMBER_OF_ITEMS_SELECTED" /></translation> <translation id="1444628761356461360">Цим налаштуванням керує власник пристрою (<ph name="OWNER_EMAIL" />).</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Після останнього введення пароля було під’єднано іншу клавіатуру. Можливо, це спроба викрасти введені символи.</translation> <translation id="1567750922576943685">Підтвердження особи допомагає захистити особисту інформацію</translation> <translation id="1567993339577891801">Консоль JavaScript</translation> -<translation id="1568067597247500137">Вимкнути звук на сайті</translation> <translation id="1568323446248056064">Відкрити налаштування дисплея</translation> <translation id="1572266655485775982">Увімкнути Wi-Fi</translation> <translation id="1572585716423026576">Зробити фоновим малюнком</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">Алгоритм ECDSA X9.62 з підписом SHA-1</translation> <translation id="1644574205037202324">Історія</translation> <translation id="1645516838734033527">Щоб захистити ваш пристрій <ph name="DEVICE_TYPE" /> за допомогою Smart Lock, потрібно налаштувати блокування екрана на телефоні.</translation> -<translation id="1646102270785326155">Якщо вилучити цього користувача, усі пов’язані з ним файли та локальні дані буде назавжди видалено. $1 усе одно зможе ввійти в обліковий запис.</translation> <translation id="1646982517418478057">Введіть пароль, щоб зашифрувати цей сертифікат</translation> <translation id="164814987133974965">Користувач, яким керує адміністратор, може переглядати веб-сайти під вашим наглядом. Як адміністратор такого користувача ви можете: <ph name="BEGIN_BOLD" />дозволяти чи забороняти<ph name="END_BOLD" /> певні веб-сайти; @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Розширення також змінило сторінку, яка відкривається під час пошуку в універсальному вікні пошуку.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Щоб видалити додатки, перейдіть у меню "Налаштування" > "Google Play" > "Змінити налаштування Android" > "Додатки" або "Менеджер додатків". Торкніться додатка (якщо потрібно, проведіть пальцем управо або вліво, щоб знайти його) і натисніть "Видалити" або "Вимкнути".<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">...</translation> -<translation id="1732215134274276513">Відкріпити вкладки</translation> <translation id="1733383495376208985">Шифрувати синхронізовані дані за допомогою <ph name="BEGIN_LINK" />парольної фрази<ph name="END_LINK" />. Це не стосується способів оплати й адрес із Google Pay.</translation> <translation id="1734824808160898225">Можливо, <ph name="PRODUCT_NAME" /> не зможе оновлюватись</translation> <translation id="1736419249208073774">Огляд</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Усі файли</translation> <translation id="1809734401532861917">Додати закладки, історію, паролі й інші налаштування в обліковий запис <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Попередній перегляд недоступний</translation> -<translation id="1812631533912615985">Відкріпити вкладки</translation> <translation id="1813278315230285598">Служби</translation> <translation id="18139523105317219">Ім'я сторони EDI</translation> <translation id="1815083418640426271">Вставити як звичайний текст</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Веб-переглядачем Chrome керує автоматична пробна програма.</translation> <translation id="2070909990982335904">Імена, які починаються з крапки, зарезервовані для системи. Виберіть інше ім’я.</translation> <translation id="2071393345806050157">Немає локального файлу журналу.</translation> -<translation id="2074527029802029717">Відмінити закріплення вкладки</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% заряду акумулятора</translation> <translation id="2075959085554270910">Можна ввімкнути або вимкнути функції натискання дотиком і перетягування дотиком</translation> <translation id="2076269580855484719">Сховати цей плагін</translation> @@ -1357,7 +1348,6 @@ <translation id="3045447014237878114">Цей сайт автоматично завантажив декілька файлів</translation> <translation id="3046910703532196514">Веб-сторінка, повністю</translation> <translation id="304747341537320566">Системи синтезу мовлення</translation> -<translation id="304826556400666995">Увімкнути звук на вкладках</translation> <translation id="3053013834507634016">Використання ключа сертифіката</translation> <translation id="3057861065630527966">Створити резервні копії фотографій і відео</translation> <translation id="3060379269883947824">Увімкнути службу Читання з екрана</translation> @@ -2343,7 +2333,6 @@ <translation id="4628762811416793313">Налаштування контейнера Linux не завершено. Повторіть спробу.</translation> <translation id="4628948037717959914">Фотографія</translation> <translation id="4631887759990505102">Виконавець</translation> -<translation id="4632483769545853758">Увімкнути звук на вкладці</translation> <translation id="4633003931260532286"><ph name="IMPORT_NAME" /> з мінімальною версією <ph name="IMPORT_VERSION" /> – це обов’язковий компонент для роботи розширення, але встановлено версію <ph name="INSTALLED_VERSION" /></translation> <translation id="4634771451598206121">Увійти знову...</translation> <translation id="4635398712689569051">Сторінка "<ph name="PAGE_NAME" />" недоступна гостям.</translation> @@ -2408,7 +2397,6 @@ <translation id="4736292055110123391">Синхронізуйте закладки, паролі, історію й інші дані на всіх своїх пристроях</translation> <translation id="4737715515457435632">Під’єднайтеся до мережі</translation> <translation id="473775607612524610">Оновити</translation> -<translation id="474217410105706308">Вимкнути звук на вкладці</translation> <translation id="4742746985488890273">Закріпити на полиці</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Дізнайтеся, як оновити додатки<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Повідомлення</translation> @@ -2633,7 +2621,6 @@ <translation id="5094721898978802975">Підтримувати зв’язок із взаємодійними рідними програмами</translation> <translation id="5097002363526479830">Не вдалося під’єднатися до мережі "<ph name="NAME" />": <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Відкрити всі закладки</translation> -<translation id="5105855035535475848">Закріпити вкладки</translation> <translation id="5108967062857032718">Налаштування – Видалення додатків Android</translation> <translation id="5109044022078737958">Краля</translation> <translation id="5111692334209731439">&Диспетчер закладок</translation> @@ -2698,7 +2685,6 @@ <translation id="520621735928254154">Не вдалось імпортувати сертифікат</translation> <translation id="5209320130288484488">Пристрої не знайдено.</translation> <translation id="5209518306177824490">Відбиток SHA-1</translation> -<translation id="5210365745912300556">Закрити вкладку</translation> <translation id="5213481667492808996">Службу передавання даних "<ph name="NAME" />" активовано</translation> <translation id="5213891612754844763">Показати налаштування проксі</translation> <translation id="521582610500777512">Фотографію відхилено</translation> @@ -2750,7 +2736,6 @@ <translation id="5272654297705279635">Власні налаштування</translation> <translation id="5275352920323889391">Собака</translation> <translation id="5275973617553375938">Відновлені файли з Google Диска</translation> -<translation id="527605719918376753">Вимкнути звук на вкладці</translation> <translation id="527605982717517565">Завжди дозволяти JavaScript на хості <ph name="HOST" /></translation> <translation id="5280426389926346830">Створити комбінацію клавіш?</translation> <translation id="528208740344463258">Щоб завантажувати й використовувати додатки Android, спершу потрібно встановити оновлення. Не користуйтеся пристроєм <ph name="DEVICE_TYPE" />, поки він оновлюється. Коли встановляться оновлення, <ph name="DEVICE_TYPE" /> перезапуститься.</translation> @@ -2873,7 +2858,6 @@ <translation id="5449551289610225147">Недійсний пароль</translation> <translation id="5449588825071916739">Зробити закладки для всіх вкладок</translation> <translation id="5449716055534515760">Закрити вік&но</translation> -<translation id="5453029940327926427">Закрити вкладки</translation> <translation id="5454166040603940656">за допомогою <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Недійсні дані</translation> <translation id="5457459357461771897">Читати й видаляти фотографії, музику та інші медіафайли на комп’ютері</translation> @@ -3338,7 +3322,6 @@ <translation id="6122875415561139701">Операцію внесення змін заборонено на пристрої <ph name="DEVICE_NAME" />.</translation> <translation id="6124650939968185064">Від цього розширення залежать такі розширення:</translation> <translation id="6125479973208104919">На жаль, потрібно ще раз додати обліковий запис на пристрої <ph name="DEVICE_TYPE" />.</translation> -<translation id="612596694132302162">Увімкнути звук на сайті</translation> <translation id="6129691635767514872">Вибрані дані видалено з Chrome і синхронізованих пристроїв. У вашому обліковому записі на сторінці <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> можуть бути інші форми історії веб-перегляду, як-от пошукові запити чи дані про активність з інших сервісів Google.</translation> <translation id="6129938384427316298">Коментар сертифіката Netscape</translation> <translation id="6129953537138746214">Пробіл</translation> @@ -3541,7 +3524,6 @@ <translation id="6436164536244065364">Переглянути у веб-магазині</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> – відтворюється аудіо</translation> <translation id="6442187272350399447">Фантастика!</translation> -<translation id="6442697326824312960">Відмінити закріплення вкладки</translation> <translation id="6444070574980481588">Вибрати дату й час</translation> <translation id="6445450263907939268">Якщо ви не хочете цих змін, можна відновити попередні налаштування.</translation> <translation id="6447842834002726250">Cookie-файли</translation> @@ -3744,7 +3726,6 @@ <translation id="6770664076092644100">Підтвердити через NFC</translation> <translation id="6771503742377376720">Є Центром сертифікації</translation> <translation id="6777817260680419853">Переспрямування заблоковано</translation> -<translation id="6778959797435875428">Увімкнути звук на сайтах</translation> <translation id="677965093459947883">Дуже малий</translation> <translation id="6780439250949340171">керувати іншими налаштуваннями</translation> <translation id="6781284683813954823">Посилання на дудл</translation> @@ -4061,7 +4042,6 @@ <translation id="7257666756905341374">Читати дані, які ви копіюєте та вставляєте</translation> <translation id="7258697411818564379">PIN-код додано</translation> <translation id="7262004276116528033">Ця служба входу в обліковий запис зареєстрована в домені <ph name="SAML_DOMAIN" /></translation> -<translation id="7268365133021434339">Закрити вкладки</translation> <translation id="7268659760406822741">Доступні сервіси</translation> <translation id="7270858098575133036">Запитувати, коли сайт хоче використовувати виключні повідомлення системи, щоб отримувати доступ до пристроїв MIDI</translation> <translation id="7272674038937250585">Немає опису</translation> @@ -4251,7 +4231,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">Сортувати за копіями</translation> <translation id="7576976045740938453">Виникла проблема з обліковим записом демо-режиму.</translation> -<translation id="7579149537961810247">Вимкнути звук на сайтах</translation> <translation id="7580671184200851182">Відтворювати один аудіозапис на всіх динаміках (монофонічне аудіо)</translation> <translation id="7581462281756524039">Інструмент очищення</translation> <translation id="7582582252461552277">Віддавати перевагу цій мережі</translation> @@ -4605,7 +4584,6 @@ <translation id="8068253693380742035">Торкніться, щоб увійти</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">Друкувати як зображення</translation> -<translation id="8072988827236813198">Закріпити вкладки</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Дані додатків – це будь-яка інформація, яку вони зберігають (залежно від налаштувань розробника), зокрема контакти, повідомлення та фотографії.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Резервні копії даних не займають місця на Диску дитини.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Цей сервіс можна вимкнути в налаштуваннях.<ph name="END_PARAGRAPH3" /></translation> @@ -4791,7 +4769,6 @@ <translation id="8368859634510605990">&Відкрити всі закладки</translation> <translation id="8371695176452482769">Диктуйте</translation> <translation id="8372369524088641025">Поганий WEP-ключ</translation> -<translation id="8373553483208508744">Вимкнути звук на вкладках</translation> <translation id="8378714024927312812">Профілем керує ваша організація</translation> <translation id="8379878387931047019">Пристрій не підтримує тип ключа безпеки, потрібний для цього веб-сайту</translation> <translation id="8382913212082956454">Копіювати &адресу електронної пошти</translation> @@ -4899,7 +4876,6 @@ <translation id="8546930481464505581">Налаштувати Touch Bar</translation> <translation id="8547013269961688403">Увімкнути лупу для всього екрана</translation> <translation id="85486688517848470">Утримуйте клавішу пошуку, щоб змінити функції клавіш угорі клавіатури</translation> -<translation id="855081842937141170">Закріпити вкладку</translation> <translation id="8551388862522347954">Ліцензії</translation> <translation id="8553342806078037065">Керувати іншими користувачами</translation> <translation id="8554899698005018844">Мову не вибрано</translation> @@ -5214,7 +5190,6 @@ <translation id="9038430547971207796">Наступного разу пристрій <ph name="DEVICE_TYPE" /> буде розблоковано за допомогою вашого телефона. Smart Lock можна вимкнути в налаштуваннях.</translation> <translation id="9038649477754266430">Користуйтеся службою передбачення, щоб сторінки завантажувалися швидше</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Вимкнути звук на вкладках</translation> <translation id="9040661932550800571">Оновити пароль для <ph name="ORIGIN" />?</translation> <translation id="9041692268811217999">Адміністратор вимкнув доступ до локальних файлів на вашому комп’ютері</translation> <translation id="9042893549633094279">Конфіденційність і безпека</translation> @@ -5312,7 +5287,6 @@ <translation id="920045321358709304">Пошук у <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Способи блокування екрана</translation> <translation id="9203398526606335860">&Профілювання ввімкнено</translation> -<translation id="9203478404496196495">Увімкнути звук на вкладці</translation> <translation id="9203904171912129171">Виберіть пристрій</translation> <translation id="9203962528777363226">Адміністратор цього пристрою вимкнув можливість додавати нових користувачів</translation> <translation id="9213073329713032541">Встановлення розпочато.</translation>
diff --git a/chrome/app/resources/generated_resources_vi.xtb b/chrome/app/resources/generated_resources_vi.xtb index 7404a87..1efadd68 100644 --- a/chrome/app/resources/generated_resources_vi.xtb +++ b/chrome/app/resources/generated_resources_vi.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">Nhấn ESCAPE để bỏ qua (Chỉ phiên bản không chính thức).</translation> <translation id="1093457606523402488">Mạng hiển thị:</translation> <translation id="1094607894174825014">Đã yêu cầu tác vụ đọc hoặc ghi với hiệu số không hợp lệ trên: "<ph name="DEVICE_NAME" />".</translation> -<translation id="109758035718544977">Bật tiếng các trang web</translation> <translation id="1097658378307015415">Trước khi đăng nhập, vui lòng đăng nhập với tư cách khách để kích hoạt mạng <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">Luôn dịch <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Dừng</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">Duyệt web mà không lưu lịch sử bằng cửa sổ ẩn danh</translation> <translation id="1213037489357051291">Đã thiết lập <ph name="NUM_FINGERPRINTS" /> vân tay</translation> <translation id="1215411991991485844">Đã thêm ứng dụng nền mới</translation> -<translation id="1216654534877302979">Tắt tiếng các trang web</translation> <translation id="1216659994753476700">Rất tiếc. Chúng tôi không truy cập được vào hồ sơ của bạn. Các tệp và dữ liệu được lưu trữ trên thiết bị này có thể đã bị mất.<ph name="BR" /> <ph name="BR" /> Bạn sẽ phải thiết lập lại hồ sơ của mình.<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">Lưu trữ dữ liệu trong tài khoản Google Drive của bạn</translation> <translation id="1288037062697528143">Chế độ ánh sáng ban đêm sẽ tự động bật khi trời tối</translation> <translation id="1288300545283011870">Thuộc tính giọng nói</translation> -<translation id="1293177648337752319">Bật tiếng trang web</translation> <translation id="1293264513303784526">Thiết bị USB-C (cổng bên trái)</translation> <translation id="1293556467332435079">Tệp</translation> <translation id="1296497012903089238">Loại chứng chỉ</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">Trang chủ là trang Tab mới</translation> <translation id="1436671784520050284">Tiếp tục thiết lập</translation> <translation id="1436784010935106834">Đã xóa</translation> -<translation id="1438632560381091872">Bật âm thanh tab</translation> <translation id="1442392616396121389">Tiền tố định tuyến</translation> <translation id="144283815522798837">Đã chọn <ph name="NUMBER_OF_ITEMS_SELECTED" /></translation> <translation id="1444628761356461360">Cài đặt này do chủ sở hữu thiết bị, <ph name="OWNER_EMAIL" /> quản lý.</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">Một bàn phím khác đã được kết nối kể từ lần gần đây nhất bạn nhập mật khẩu của mình. Bàn phím này có thể đang cố gắng đánh cắp thao tác nhấn phím của bạn.</translation> <translation id="1567750922576943685">Việc xác minh thông tin định danh giúp bảo vệ thông tin cá nhân của bạn</translation> <translation id="1567993339577891801">Bảng điều khiển JavaScript</translation> -<translation id="1568067597247500137">Tắt tiếng trang web</translation> <translation id="1568323446248056064">Mở cài đặt thiết bị hiển thị</translation> <translation id="1572266655485775982">Bật Wi-Fi</translation> <translation id="1572585716423026576">Đặt làm hình nền</translation> @@ -440,7 +435,6 @@ <translation id="1643072738649235303">Chữ ký X9.62 ECDSA với SHA-1</translation> <translation id="1644574205037202324">Lịch sử</translation> <translation id="1645516838734033527">Để giữ an toàn cho <ph name="DEVICE_TYPE" />, Smart Lock yêu cầu phải bật khóa màn hình trên điện thoại của bạn.</translation> -<translation id="1646102270785326155">Tất cả các tệp và dữ liệu cục bộ được liên kết vớ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. $1 vẫn có thể đăng nhập sau đó.</translation> <translation id="1646982517418478057">Vui lòng nhập mật khẩu để mã hóa chứng chỉ này</translation> <translation id="164814987133974965">Người dùng được giám sát có thể khám phá web dưới sự hướng dẫn của bạn. Là người quản lý của người dùng được giám sát, bạn có thể <ph name="BEGIN_BOLD" />cho phép hoặc cấm<ph name="END_BOLD" /> các trang web nhất định, @@ -499,7 +493,6 @@ <translation id="1729533290416704613">Tiện ích này cũng điều khiển trang nào được hiển thị khi bạn tìm kiếm từ Thanh địa chỉ.</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />Để xóa ứng dụng, hãy chuyển đến mục Cài đặt > Cửa hàng Google Play > Quản lý tùy chọn Android > Ứng dụng hoặc Trình quản lý ứng dụng. Sau đó, nhấn vào ứng dụng bạn muốn gỡ cài đặt (bạn có thể phải vuốt sang phải hoặc sang trái để tìm ứng dụng). Sau đó, nhấn vào Gỡ cài đặt hoặc Tắt.<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">Đang gửi yêu cầu…</translation> -<translation id="1732215134274276513">Bỏ gắn các tab</translation> <translation id="1733383495376208985">Mã hóa dữ liệu đã đồng bộ hóa bằng <ph name="BEGIN_LINK" />cụm mật khẩu đồng bộ hóa<ph name="END_LINK" /> của riêng bạn. Việc này không bao gồm địa chỉ và phương thức thanh toán từ Google Pay.</translation> <translation id="1734824808160898225"><ph name="PRODUCT_NAME" /> có thể không tự cập nhật được</translation> <translation id="1736419249208073774">Khám phá</translation> @@ -551,7 +544,6 @@ <translation id="1807938677607439181">Tất cả các tệp</translation> <translation id="1809734401532861917">Thêm dấu trang, lịch sử, mật khẩu của tôi và các cài đặt khác vào <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">Không có bản xem trước</translation> -<translation id="1812631533912615985">Bỏ gắn các tab</translation> <translation id="1813278315230285598">Dịch vụ</translation> <translation id="18139523105317219">Tên của Bên EDI</translation> <translation id="1815083418640426271">Dán dưới dạng văn bản thuần túy</translation> @@ -710,7 +702,6 @@ <translation id="2065405795449409761">Chrome đang được phần mềm kiểm tra tự động kiểm soát.</translation> <translation id="2070909990982335904">Các tên bắt đầu với dấu chấm được dành riêng cho hệ thống. Vui lòng chọn tên khác.</translation> <translation id="2071393345806050157">Không có tệp nhật ký cục bộ.</translation> -<translation id="2074527029802029717">Bỏ gắn tab</translation> <translation id="2075474481720804517"><ph name="BATTERY_PERCENTAGE" />% pin</translation> <translation id="2075959085554270910">Cho phép bạn bật/tắt tính năng chạm để nhấp và kéo nhấn</translation> <translation id="2076269580855484719">Ẩn plugin này</translation> @@ -1352,7 +1343,6 @@ <translation id="3045447014237878114">Trang web này đã tự động tải nhiều tệp xuống</translation> <translation id="3046910703532196514">Trang web, toàn bộ</translation> <translation id="304747341537320566">Công cụ chuyển văn bản sang lời nói</translation> -<translation id="304826556400666995">Bật âm thanh tab</translation> <translation id="3053013834507634016">Sử dụng Khoá Chứng chỉ</translation> <translation id="3057861065630527966">Sao lưu ảnh và video của bạn</translation> <translation id="3060379269883947824">Bật chọn để nói</translation> @@ -2335,7 +2325,6 @@ <translation id="4628762811416793313">Quá trình thiết lập vùng chứa Linux chưa hoàn tất. Vui lòng thử lại.</translation> <translation id="4628948037717959914">Ảnh</translation> <translation id="4631887759990505102">Nghệ sĩ</translation> -<translation id="4632483769545853758">Bật âm thanh tab</translation> <translation id="4633003931260532286">Tiện ích yêu cầu "<ph name="IMPORT_NAME" />" có phiên bản tối thiểu "<ph name="IMPORT_VERSION" />" nhưng mới chỉ cài đặt được phiên bản "<ph name="INSTALLED_VERSION" />"</translation> <translation id="4634771451598206121">Đăng nhập lại...</translation> <translation id="4635398712689569051">Người dùng khách không thể sử dụng <ph name="PAGE_NAME" />.</translation> @@ -2399,7 +2388,6 @@ <translation id="4735803855089279419">Hệ thống không xác định được mã nhận dạng thiết bị cho thiết bị này.</translation> <translation id="4737715515457435632">Hãy kết nối với mạng</translation> <translation id="473775607612524610">Cập nhật</translation> -<translation id="474217410105706308">Tắt tiếng tab</translation> <translation id="4742746985488890273">Ghim vào giá</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Tìm hiểu cách cập nhật ứng dụng<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Tin nhắn</translation> @@ -2624,7 +2612,6 @@ <translation id="5094721898978802975">Kết nối với ứng dụng gốc hợp tác</translation> <translation id="5097002363526479830">Không thể kết nối với mạng '<ph name="NAME" />': <ph name="DETAILS" /></translation> <translation id="5101042277149003567">Mở tất cả dấu trang</translation> -<translation id="5105855035535475848">Ghim các tab</translation> <translation id="5108967062857032718">Cài đặt - Xóa ứng dụng Android</translation> <translation id="5109044022078737958">Nữ cầu thủ Mia</translation> <translation id="5111692334209731439">&Trình quản lý Dấu trang</translation> @@ -2689,7 +2676,6 @@ <translation id="520621735928254154">Lỗi nhập chứng chỉ</translation> <translation id="5209320130288484488">Không tìm thấy thiết bị nào</translation> <translation id="5209518306177824490">SHA-1 Fingerprint</translation> -<translation id="5210365745912300556">Đóng tab</translation> <translation id="5213481667492808996">Dịch vụ dữ liệu '<ph name="NAME" />' đã sẵn sàng cho bạn sử dụng</translation> <translation id="5213891612754844763">Hiển thị cài đặt proxy</translation> <translation id="521582610500777512">Đã hủy ảnh</translation> @@ -2740,7 +2726,6 @@ <translation id="5270167208902136840">Hiển thị <ph name="NUMBER_OF_MORE_APPS" /> ứng dụng khác</translation> <translation id="5275352920323889391">Cún</translation> <translation id="5275973617553375938">Tệp được khôi phục từ Google Drive</translation> -<translation id="527605719918376753">Tắt tiếng tab</translation> <translation id="527605982717517565">Luôn cho phép JavaScript trên <ph name="HOST" /></translation> <translation id="5280426389926346830">Tạo lối tắt?</translation> <translation id="528208740344463258">Để tải xuống và dùng các ứng dụng Android, trước tiên, bạn cần cài đặt bản cập nhật bắt buộc này. Bạn sẽ không thể sử dụng <ph name="DEVICE_TYPE" /> trong khi thiết bị đang cập nhật. <ph name="DEVICE_TYPE" /> sẽ khởi động lại sau khi quá trình cài đặt hoàn tất.</translation> @@ -2863,7 +2848,6 @@ <translation id="5449551289610225147">Mật khẩu không hợp lệ</translation> <translation id="5449588825071916739">Đánh dấu trang tất cả các tab</translation> <translation id="5449716055534515760">Đóng cửa &sổ</translation> -<translation id="5453029940327926427">Đóng các tab</translation> <translation id="5454166040603940656">với <ph name="PROVIDER" /></translation> <translation id="5457113250005438886">Không hợp lệ</translation> <translation id="5457459357461771897">Đọc và xóa ảnh, nhạc và các phương tiện khác khỏi máy tính của bạn</translation> @@ -3328,7 +3312,6 @@ <translation id="6122875415561139701">Tác vụ ghi không được phép trên: "<ph name="DEVICE_NAME" />".</translation> <translation id="6124650939968185064">Các tiện ích sau phụ thuộc vào tiện ích này:</translation> <translation id="6125479973208104919">Rất tiếc, bạn sẽ cần phải thêm lại tài khoản của mình vào <ph name="DEVICE_TYPE" /> này.</translation> -<translation id="612596694132302162">Bật tiếng trang web</translation> <translation id="6129691635767514872">Dữ liệu được chọn đã bị xóa khỏi Chrome và các thiết bị được đồng bộ hóa. Tài khoản Google của bạn có thể có các dạng lịch sử duyệt web khác, chẳng hạn như tìm kiếm và hoạt động từ các dịch vụ khác của Google tại <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="6129938384427316298">Nhận xét về Chứng chỉ Netscape</translation> <translation id="6129953537138746214">Dấu cách</translation> @@ -3531,7 +3514,6 @@ <translation id="6436164536244065364">Xem trong Cửa hàng trực tuyến</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - Phát âm thanh</translation> <translation id="6442187272350399447">Tuyệt vời</translation> -<translation id="6442697326824312960">Bỏ gắn Tab</translation> <translation id="6444070574980481588">Đặt ngày giờ</translation> <translation id="6445450263907939268">Nếu không thích những thay đổi này, bạn có thể khôi phục cài đặt trước của mình.</translation> <translation id="6447842834002726250">Cookie</translation> @@ -3734,7 +3716,6 @@ <translation id="6770664076092644100">Xác minh qua NFC</translation> <translation id="6771503742377376720">Là Tổ chức phát hành chứng chỉ</translation> <translation id="6777817260680419853">Đã chặn chuyển hướng</translation> -<translation id="6778959797435875428">Bật tiếng các trang web</translation> <translation id="677965093459947883">Rất nhỏ</translation> <translation id="6780439250949340171">quản lý các cài đặt khác</translation> <translation id="6781284683813954823">Liên kết Doodle</translation> @@ -4051,7 +4032,6 @@ <translation id="7257666756905341374">Đọc dữ liệu bạn sao chép và dán</translation> <translation id="7258697411818564379">Bạn đã thêm mã PIN</translation> <translation id="7262004276116528033">Dịch vụ đăng nhập này do <ph name="SAML_DOMAIN" /> lưu trữ</translation> -<translation id="7268365133021434339">Đóng tab</translation> <translation id="7268659760406822741">Dịch vụ khả dụng</translation> <translation id="7270858098575133036">Hỏi tôi khi có trang web muốn sử dụng thông báo dành riêng cho hệ thống để truy cập thiết bị MIDI</translation> <translation id="7272674038937250585">Chưa có mô tả</translation> @@ -4241,7 +4221,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">Đối chiếu</translation> <translation id="7576976045740938453">Đã xảy ra lỗi với tài khoản chế độ minh họa.</translation> -<translation id="7579149537961810247">Tắt tiếng các trang web</translation> <translation id="7580671184200851182">Phát cùng một âm thanh qua tất cả các loa (đơn âm)</translation> <translation id="7581462281756524039">Công cụ làm sạch</translation> <translation id="7582582252461552277">Thích mạng này</translation> @@ -4595,7 +4574,6 @@ <translation id="8068253693380742035">Chạm để đăng nhập</translation> <translation id="8069615408251337349">Google Cloud Print</translation> <translation id="8071432093239591881">In dưới dạng hình ảnh</translation> -<translation id="8072988827236813198">Ghim các tab</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />Dữ liệu ứng dụng có thể là bất kỳ dữ liệu nào mà một ứng dụng đã lưu (dựa trên tùy chọn cài đặt của nhà phát triển), bao gồm cả dữ liệu như danh bạ, tin nhắn và ảnh.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Dữ liệu sao lưu sẽ không tính vào hạn mức bộ nhớ Drive của con bạn.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Bạn có thể tắt dịch vụ này trong mục Cài đặt.<ph name="END_PARAGRAPH3" /></translation> @@ -4781,7 +4759,6 @@ <translation id="8368859634510605990">&Mở tất cả dấu trang</translation> <translation id="8371695176452482769">Nói ngay bây giờ</translation> <translation id="8372369524088641025">Khóa WEP sai</translation> -<translation id="8373553483208508744">Tắt tiếng tab</translation> <translation id="8378714024927312812">Do tổ chức của bạn quản lý</translation> <translation id="8379878387931047019">Thiết bị này không hỗ trợ loại khóa bảo mật mà trang web này yêu cầu</translation> <translation id="8382913212082956454">Sao chép địa chỉ &email</translation> @@ -4889,7 +4866,6 @@ <translation id="8546930481464505581">Tùy chỉnh Thanh cảm ứng</translation> <translation id="8547013269961688403">Bật tính năng phóng to toàn bộ màn hình</translation> <translation id="85486688517848470">Giữ phím Tìm kiếm để chuyển đổi chức năng của các phím hàng trên cùng</translation> -<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> @@ -5203,7 +5179,6 @@ <translation id="9038430547971207796">Lần tới, điện thoại của bạn sẽ mở khóa <ph name="DEVICE_TYPE" />. Hãy tắt Smart Lock trong Cài đặt.</translation> <translation id="9038649477754266430">Sử dụng dịch vụ gợi ý để tải trang nhanh hơn</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">Tắt tiếng tab</translation> <translation id="9040661932550800571">Bạn có muốn cập nhật mật khẩu cho <ph name="ORIGIN" /> không?</translation> <translation id="9041692268811217999">Quản trị viên đã vô hiệu hóa quyền truy cập vào tệp cục bộ trên máy của bạn</translation> <translation id="9042893549633094279">Quyền riêng tư và bảo mật</translation> @@ -5301,7 +5276,6 @@ <translation id="920045321358709304">Tìm kiếm trên <ph name="SEARCH_ENGINE" /></translation> <translation id="9201220332032049474">Tùy chọn khóa màn hình</translation> <translation id="9203398526606335860">&Bật cấu hình</translation> -<translation id="9203478404496196495">Bật âm thanh tab</translation> <translation id="9203904171912129171">Chọn thiết bị</translation> <translation id="9203962528777363226">Quản trị viên của thiết bị này đã vô hiệu hóa thêm người dùng mới</translation> <translation id="9213073329713032541">Đã bắt đầu thành công quá trình cài đặt.</translation>
diff --git a/chrome/app/resources/generated_resources_zh-CN.xtb b/chrome/app/resources/generated_resources_zh-CN.xtb index a6497e6b..305af599 100644 --- a/chrome/app/resources/generated_resources_zh-CN.xtb +++ b/chrome/app/resources/generated_resources_zh-CN.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">按 ESC 键可跳过更新(仅限非官方版本)。</translation> <translation id="1093457606523402488">可见网络:</translation> <translation id="1094607894174825014">有人使用无效偏移值在“<ph name="DEVICE_NAME" />”上请求了读取或写入操作。</translation> -<translation id="109758035718544977">将多个网站取消静音</translation> <translation id="1097658378307015415">登录前,请先以访客身份进入,以便激活“<ph name="NETWORK_ID" />”网络。</translation> <translation id="1103523840287552314">一律翻译<ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">停止(&S)</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">如果您使用无痕式窗口浏览网页,系统便不会保存您的浏览记录</translation> <translation id="1213037489357051291">已设置 <ph name="NUM_FINGERPRINTS" /> 个指纹</translation> <translation id="1215411991991485844">已添加新的后台应用</translation> -<translation id="1216654534877302979">将多个网站静音</translation> <translation id="1216659994753476700">很抱歉,我们无法访问您的个人资料。这台设备上存储的文件和数据可能已丢失。<ph name="BR" /> <ph name="BR" /> 您必须重新设置个人资料。<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">将数据存储在您的 Google 云端硬盘帐号中</translation> <translation id="1288037062697528143">夜间模式将于日落时自动开启</translation> <translation id="1288300545283011870">语音属性</translation> -<translation id="1293177648337752319">将单个网站取消静音</translation> <translation id="1293264513303784526">USB-C 设备(左侧端口)</translation> <translation id="1293556467332435079">文件</translation> <translation id="1296497012903089238">证书类型</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">首页是新标签页</translation> <translation id="1436671784520050284">继续设置</translation> <translation id="1436784010935106834">已删除</translation> -<translation id="1438632560381091872">将所有标签页取消静音</translation> <translation id="1442392616396121389">路由前缀</translation> <translation id="144283815522798837">已选择 <ph name="NUMBER_OF_ITEMS_SELECTED" /> 项</translation> <translation id="1444628761356461360">此设置由设备所有者<ph name="OWNER_EMAIL" />管理。</translation> @@ -385,7 +381,6 @@ <translation id="1567387640189251553">自从您上次输入密码后,所连接的键盘已被更换。当前连接的键盘可能会试图窃取您的击键操作。</translation> <translation id="1567750922576943685">验证您的身份有助于保护您的个人信息</translation> <translation id="1567993339577891801">JavaScript 控制台</translation> -<translation id="1568067597247500137">将单个网站静音</translation> <translation id="1568323446248056064">打开显示设备设置</translation> <translation id="1572266655485775982">Wi-Fi 开关</translation> <translation id="1572585716423026576">设为壁纸</translation> @@ -437,7 +432,6 @@ <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="1646982517418478057">请输入密码,用于加密该证书</translation> <translation id="164814987133974965">受监管用户可以在您的指导下浏览网页。作为受监管用户的管理员,您可以执行以下操作: <ph name="BEGIN_BOLD" />允许或禁止<ph name="END_BOLD" />访问某些网站, @@ -496,7 +490,6 @@ <translation id="1729533290416704613">它还能够控制您通过多功能框进行搜索时系统显示的页面。</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />要想卸载应用,请依次转到“设置”>“Google Play 商店”>“管理 Android 偏好设置”>“应用”或“应用管理器”,点按您要卸载的应用(您可能需要左右滑动才能找到相应的应用),然后点按“卸载”或“停用”。<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">正在发送请求...</translation> -<translation id="1732215134274276513">取消固定标签页</translation> <translation id="1733383495376208985">使用您自己的<ph name="BEGIN_LINK" />同步密码<ph name="END_LINK" />加密已同步的数据。这并不包括 Google Pay 中的付款方式和地址。</translation> <translation id="1734824808160898225">“<ph name="PRODUCT_NAME" />”可能无法自动更新</translation> <translation id="1736419249208073774">探索</translation> @@ -548,7 +541,6 @@ <translation id="1807938677607439181">所有文件</translation> <translation id="1809734401532861917">将我的书签、历史记录、密码和其他设置添加至 <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">无法预览</translation> -<translation id="1812631533912615985">取消固定标签页</translation> <translation id="1813278315230285598">服务</translation> <translation id="18139523105317219">EDI 参与方名称</translation> <translation id="1815083418640426271">粘贴为纯文本</translation> @@ -707,7 +699,6 @@ <translation id="2065405795449409761">Chrome 正受到自动测试软件的控制。</translation> <translation id="2070909990982335904">以点开头的名称仅适用于系统文件,请选择其他名称。</translation> <translation id="2071393345806050157">没有本地日志文件。</translation> -<translation id="2074527029802029717">取消固定标签页</translation> <translation id="2075474481720804517">电池电量:<ph name="BATTERY_PERCENTAGE" />%</translation> <translation id="2075959085554270910">可让您启用/停用“点按即点击”功能和“点按拖动”功能</translation> <translation id="2076269580855484719">隐藏此插件</translation> @@ -770,6 +761,7 @@ <translation id="215753907730220065">退出全屏模式</translation> <translation id="2157875535253991059">此网页现处于全屏模式。</translation> <translation id="216169395504480358">添加 Wi-Fi...</translation> +<translation id="2162155940152307086">一旦您离开同步设置页面,同步功能就会启动</translation> <translation id="2163470535490402084">请连接到互联网,以便登录您的<ph name="DEVICE_TYPE" />。</translation> <translation id="2166369534954157698">The quick brown fox jumps over the lazy dog</translation> <translation id="2169062631698640254">仍然登录</translation> @@ -780,6 +772,7 @@ <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_DOMAIN" /> 上的“<ph name="PEPPER_PLUGIN_NAME" />”想访问您的计算机</translation> <translation id="2178614541317717477">CA 泄漏</translation> <translation id="218070003709087997">用数字表示要打印多少份(1 到 999 份)。</translation> +<translation id="2182253583899676504">您在文本字段中输入的文字将会被发送给 Google。</translation> <translation id="2184515124301515068">让 Chrome 选择何时允许网站播放声音(推荐)</translation> <translation id="2187895286714876935">服务器证书导入错误</translation> <translation id="2187906491731510095">扩展程序已更新</translation> @@ -791,7 +784,9 @@ <translation id="2192505247865591433">来源:</translation> <translation id="2193365732679659387">信任设置</translation> <translation id="2195729137168608510">电子邮件保护</translation> +<translation id="2198757192731523470">Google 可能会利用您的历史记录为您提供个性化的 Google 搜索、广告和其他 Google 服务。</translation> <translation id="2199298570273670671">错误</translation> +<translation id="2199719347983604670">Chrome 同步的数据</translation> <translation id="2200094388063410062">电子邮件</translation> <translation id="2200356397587687044">Chrome 需要获得相应权限才能继续</translation> <translation id="2200603218210188859">USB 设备偏好设置</translation> @@ -1247,6 +1242,7 @@ <translation id="2889064240420137087">链接打开方式...</translation> <translation id="2889925978073739256">继续拦截未经过沙盒屏蔽的插件</translation> <translation id="2893168226686371498">默认浏览器</translation> +<translation id="2895734772884435517">您可以随时自定义这些设置。</translation> <translation id="289644616180464099">SIM 卡已被锁定</translation> <translation id="289695669188700754">密钥 ID:<ph name="KEY_ID" /></translation> <translation id="2897878306272793870">是否确实要打开 <ph name="TAB_COUNT" /> 个标签页?</translation> @@ -1347,7 +1343,6 @@ <translation id="3045447014237878114">此网站已自动下载多个文件</translation> <translation id="3046910703532196514">网页,全部</translation> <translation id="304747341537320566">语音引擎</translation> -<translation id="304826556400666995">将所有标签页取消静音</translation> <translation id="3053013834507634016">证书密钥用法</translation> <translation id="3057861065630527966">备份您的照片和视频</translation> <translation id="3060379269883947824">启用“随选朗读”</translation> @@ -1714,6 +1709,7 @@ <translation id="3636096452488277381"><ph name="USER_GIVEN_NAME" />,您好!</translation> <translation id="3636766455281737684"><ph name="PERCENTAGE" />% - 还可使用 <ph name="TIME" /></translation> <translation id="3637682276779847508">如果您无法输入正确的 PIN 码解锁密钥,您的 SIM 卡将被永久停用。</translation> +<translation id="363863692969456324">通过增强的“拼写检查”功能修正拼写错误</translation> <translation id="3640214691812501263">要为<ph name="USER_NAME" />添加“<ph name="EXTENSION_NAME" />”吗?</translation> <translation id="3644896802912593514">宽度</translation> <translation id="3645372836428131288">请稍微移动一下手指,以便系统记录您指纹的不同部分。</translation> @@ -2145,6 +2141,7 @@ <translation id="4310139701823742692">文件格式有误。请检查 PPD 文件,然后重试。</translation> <translation id="431076611119798497">详细信息(&D)</translation> <translation id="4312866146174492540">屏蔽(默认)</translation> +<translation id="4314815835985389558">管理同步数据</translation> <translation id="4316850752623536204">开发者网站</translation> <translation id="4320177379694898372">未连接到互联网</translation> <translation id="4320948194796820126">为您的电子邮件添加书签</translation> @@ -2224,6 +2221,7 @@ <translation id="4450974146388585462">诊断</translation> <translation id="4451757071857432900">已禁止会展示侵扰性或误导性广告的网站显示广告(推荐)</translation> <translation id="4453946976636652378">在<ph name="SEARCH_ENGINE_NAME" />中搜索,或者输入一个网址</translation> +<translation id="4461835665417498653">将一些系统信息和网页内容匿名发送给 Google。</translation> <translation id="4462159676511157176">自定义域名服务器</translation> <translation id="4467101674048705704">展开“<ph name="FOLDER_NAME" />”</translation> <translation id="4469477701382819144">已禁止会展示侵扰性或误导性广告的网站显示广告</translation> @@ -2327,7 +2325,6 @@ <translation id="4628762811416793313">未完成 Linux 容器设置。请重试。</translation> <translation id="4628948037717959914">照片</translation> <translation id="4631887759990505102">艺术家</translation> -<translation id="4632483769545853758">将此标签页取消静音</translation> <translation id="4633003931260532286">此扩展程序要求“<ph name="IMPORT_NAME" />”的版本不得低于“<ph name="IMPORT_VERSION" />”,但目前安装的版本只是“<ph name="INSTALLED_VERSION" />”</translation> <translation id="4634771451598206121">重新登录...</translation> <translation id="4635398712689569051">访客用户无法使用“<ph name="PAGE_NAME" />”页面。</translation> @@ -2389,9 +2386,9 @@ <translation id="4735265153267957659">请输入您的密码,以启用 Smart Lock。下次,您只需使用手机就能解锁您的 <ph name="DEVICE_TYPE" /> 了。您可在“设置”中关闭 Smart Lock。</translation> <translation id="473546211690256853">此帐号由 <ph name="DOMAIN" /> 管理</translation> <translation id="4735803855089279419">系统未能识别此设备的设备标识符。</translation> +<translation id="4736292055110123391">将您的书签、密码、历史记录等信息同步到您的所有设备上</translation> <translation id="4737715515457435632">请连接到网络</translation> <translation id="473775607612524610">更新</translation> -<translation id="474217410105706308">将此标签页静音</translation> <translation id="4742746985488890273">固定到任务栏</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />了解如何更新应用<ph name="END_LINK" /></translation> <translation id="4746351372139058112">信息</translation> @@ -2616,7 +2613,6 @@ <translation id="5094721898978802975">与协作的本机应用通信</translation> <translation id="5097002363526479830">无法连接到网络“<ph name="NAME" />”:<ph name="DETAILS" /></translation> <translation id="5101042277149003567">打开所有书签</translation> -<translation id="5105855035535475848">固定标签页</translation> <translation id="5108967062857032718">设置 - 移除 Android 应用</translation> <translation id="5109044022078737958">女运动员</translation> <translation id="5111692334209731439">书签管理器(&B)</translation> @@ -2681,7 +2677,6 @@ <translation id="520621735928254154">导入证书时出现错误</translation> <translation id="5209320130288484488">未找到任何设备</translation> <translation id="5209518306177824490">SHA-1 指纹</translation> -<translation id="5210365745912300556">关闭标签页</translation> <translation id="5213481667492808996">您可以使用“<ph name="NAME" />”的数据流量服务了</translation> <translation id="5213891612754844763">显示代理设置</translation> <translation id="521582610500777512">照片已被舍弃</translation> @@ -2725,9 +2720,9 @@ <translation id="5266113311903163739">证书授权中心导入错误</translation> <translation id="5269977353971873915">打印失败</translation> <translation id="5270167208902136840">显示另外 <ph name="NUMBER_OF_MORE_APPS" /> 个应用</translation> +<translation id="5272654297705279635">自定义设置</translation> <translation id="5275352920323889391">狗</translation> <translation id="5275973617553375938">从 Google 云端硬盘恢复的文件</translation> -<translation id="527605719918376753">将此标签页静音</translation> <translation id="527605982717517565">始终允许使用 <ph name="HOST" /> 上的 JavaScript</translation> <translation id="5280426389926346830">创建快捷方式?</translation> <translation id="528208740344463258">要下载并使用 Android 应用,请先安装这项必不可少的更新。在您的<ph name="DEVICE_TYPE" />进行更新期间,您将无法使用此设备。待安装完毕后,您的<ph name="DEVICE_TYPE" />将会重启。</translation> @@ -2850,7 +2845,6 @@ <translation id="5449551289610225147">密码无效</translation> <translation id="5449588825071916739">为所有标签页添加书签</translation> <translation id="5449716055534515760">关闭窗口(&D)</translation> -<translation id="5453029940327926427">关闭标签页</translation> <translation id="5454166040603940656">提供方:<ph name="PROVIDER" /></translation> <translation id="5457113250005438886">无效</translation> <translation id="5457459357461771897">读取和删除您计算机上的照片、音乐和其他媒体</translation> @@ -3315,7 +3309,6 @@ <translation id="6122875415561139701">禁止在“<ph name="DEVICE_NAME" />”上执行写入操作。</translation> <translation id="6124650939968185064">需先安装此扩展程序,下列扩展程序才能正常使用:</translation> <translation id="6125479973208104919">抱歉,您需要再次向此 <ph name="DEVICE_TYPE" /> 添加您的帐号。</translation> -<translation id="612596694132302162">将单个网站取消静音</translation> <translation id="6129691635767514872">系统已从 Chrome 和同步的设备中移除了您所选的数据。不过,您的 Google 帐号在 <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> 上可能还有其他形式的浏览记录(例如,在其他 Google 服务中的搜索记录和活动记录)。</translation> <translation id="6129938384427316298">Netscape 证书评论</translation> <translation id="6129953537138746214">空格</translation> @@ -3518,7 +3511,6 @@ <translation id="6436164536244065364">在 Chrome 网上应用店中查看</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - 正在播放音频</translation> <translation id="6442187272350399447">棒极了</translation> -<translation id="6442697326824312960">取消固定标签页</translation> <translation id="6444070574980481588">设置日期和时间</translation> <translation id="6445450263907939268">如果您不想保留这些更改,可以还原之前的设置。</translation> <translation id="6447842834002726250">Cookie</translation> @@ -3721,7 +3713,6 @@ <translation id="6770664076092644100">通过 NFC 进行验证</translation> <translation id="6771503742377376720">是证书授权中心</translation> <translation id="6777817260680419853">已阻止重定向</translation> -<translation id="6778959797435875428">将多个网站取消静音</translation> <translation id="677965093459947883">特小</translation> <translation id="6780439250949340171">管理其他设置</translation> <translation id="6781284683813954823">涂鸦链接</translation> @@ -4038,7 +4029,6 @@ <translation id="7257666756905341374">读取您复制和粘贴的数据</translation> <translation id="7258697411818564379">您的 PIN 码已添加</translation> <translation id="7262004276116528033">此登录服务由 <ph name="SAML_DOMAIN" /> 托管</translation> -<translation id="7268365133021434339">关闭标签页</translation> <translation id="7268659760406822741">可用服务</translation> <translation id="7270858098575133036">当网站想使用系统专有消息访问 MIDI 设备时询问您</translation> <translation id="7272674038937250585">未提供说明</translation> @@ -4226,7 +4216,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">自动分页</translation> <translation id="7576976045740938453">演示模式帐号出问题了。</translation> -<translation id="7579149537961810247">将多个网站静音</translation> <translation id="7580671184200851182">在所有音响设备上播放相同的音频(单声道音频)</translation> <translation id="7581462281756524039">清理工具</translation> <translation id="7582582252461552277">首选此网络</translation> @@ -4580,7 +4569,6 @@ <translation id="8068253693380742035">触摸以登录</translation> <translation id="8069615408251337349">Google 云打印</translation> <translation id="8071432093239591881">以图片形式打印</translation> -<translation id="8072988827236813198">固定标签页</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />应用数据可以是应用根据开发者设置而保存的任何数据,包括通讯录、邮件/消息、照片等数据。<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />备份数据不会计入您孩子的云端硬盘存储空间配额。<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />您可在“设置”部分中关闭此服务。<ph name="END_PARAGRAPH3" /></translation> @@ -4765,7 +4753,6 @@ <translation id="8368859634510605990">打开所有书签(&O)</translation> <translation id="8371695176452482769">请开始说话</translation> <translation id="8372369524088641025">WEP 密钥错误</translation> -<translation id="8373553483208508744">将所有标签页静音</translation> <translation id="8378714024927312812">由贵单位管理</translation> <translation id="8379878387931047019">此设备不支持该网站要求使用的安全密钥的类型</translation> <translation id="8382913212082956454">复制电子邮件地址(&E)</translation> @@ -4873,7 +4860,6 @@ <translation id="8546930481464505581">自定义触摸栏</translation> <translation id="8547013269961688403">启用全屏放大镜</translation> <translation id="85486688517848470">按住搜索键可切换顶行键的行为</translation> -<translation id="855081842937141170">固定标签页</translation> <translation id="8551388862522347954">许可</translation> <translation id="8553342806078037065">管理其他用户</translation> <translation id="8554899698005018844">无语言</translation> @@ -4903,6 +4889,7 @@ <translation id="8598453409908276158">已拦截未经过沙盒屏蔽的插件</translation> <translation id="8601206103050338563">TLS WWW 客户端身份验证</translation> <translation id="8602851771975208551">您计算机上的其他程序添加了一个应用,该应用可能会改变 Chrome 的工作方式。</translation> +<translation id="8604763363205185560">帮助改进 Chrome 并提高其安全性</translation> <translation id="8605428685123651449">SQLite 使用的内存</translation> <translation id="8606726445206553943">使用您的 MIDI 设备</translation> <translation id="8609465669617005112">上移</translation> @@ -5187,7 +5174,6 @@ <translation id="9038430547971207796">下次,您就能使用配对手机解锁您的 <ph name="DEVICE_TYPE" /> 了。您可在“设置”中关闭 Smart Lock。</translation> <translation id="9038649477754266430">使用联想查询服务更快速地加载网页</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">将所有标签页静音</translation> <translation id="9040661932550800571">要更新 <ph name="ORIGIN" /> 的密码吗?</translation> <translation id="9041692268811217999">您的管理员已禁止访问您计算机上的本地文件</translation> <translation id="9042893549633094279">隐私设置和安全性</translation> @@ -5285,7 +5271,6 @@ <translation id="920045321358709304">在<ph name="SEARCH_ENGINE" />中搜索</translation> <translation id="9201220332032049474">屏幕锁定选项</translation> <translation id="9203398526606335860">分析已启用(&P)</translation> -<translation id="9203478404496196495">将此标签页取消静音</translation> <translation id="9203904171912129171">选择设备</translation> <translation id="9203962528777363226">此设备的管理员已禁止添加新用户</translation> <translation id="9213073329713032541">安装已成功启动。</translation>
diff --git a/chrome/app/resources/generated_resources_zh-TW.xtb b/chrome/app/resources/generated_resources_zh-TW.xtb index 9f75bbc..c6fcf45 100644 --- a/chrome/app/resources/generated_resources_zh-TW.xtb +++ b/chrome/app/resources/generated_resources_zh-TW.xtb
@@ -69,7 +69,6 @@ <translation id="1091767800771861448">按下 ESCAPE 鍵可略過 (僅限非官方版本)。</translation> <translation id="1093457606523402488">可偵測到的網路:</translation> <translation id="1094607894174825014">在以下裝置上要求的讀取或寫入作業使用了無效的偏移:「<ph name="DEVICE_NAME" />」。</translation> -<translation id="109758035718544977">開啟多個網站音訊</translation> <translation id="1097658378307015415">請在登入前以訪客身分進入,啟用網路 <ph name="NETWORK_ID" /></translation> <translation id="1103523840287552314">一律翻譯<ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">停止(&S)</translation> @@ -156,7 +155,6 @@ <translation id="1211364473545090084">如果不希望系統在你使用網路時儲存你的瀏覽記錄,請使用無痕式視窗</translation> <translation id="1213037489357051291">已設定 <ph name="NUM_FINGERPRINTS" /> 枚指紋</translation> <translation id="1215411991991485844">已新增新的背景應用程式</translation> -<translation id="1216654534877302979">關閉多個網站音訊</translation> <translation id="1216659994753476700">很抱歉,系統無法存取您的設定檔。儲存在這個裝置上的檔案和資料可能已經遺失。<ph name="BR" /> <ph name="BR" /> 您必須重新建立設定檔。<ph name="BR" /> @@ -206,7 +204,6 @@ <translation id="1285484354230578868">將資料儲存在 Google 雲端硬碟帳戶中</translation> <translation id="1288037062697528143">夜燈功能將於日落時自動開啟</translation> <translation id="1288300545283011870">語音屬性</translation> -<translation id="1293177648337752319">開啟網站音訊</translation> <translation id="1293264513303784526">USB-C 裝置 (左側連接埠)</translation> <translation id="1293556467332435079">檔案</translation> <translation id="1296497012903089238">憑證類型</translation> @@ -305,7 +302,6 @@ <translation id="1434886155212424586">首頁是新分頁</translation> <translation id="1436671784520050284">繼續設定</translation> <translation id="1436784010935106834">已移除</translation> -<translation id="1438632560381091872">開啟多個分頁音訊</translation> <translation id="1442392616396121389">路徑前置字元</translation> <translation id="144283815522798837">已選取 <ph name="NUMBER_OF_ITEMS_SELECTED" /> 個項目</translation> <translation id="1444628761356461360">這項設定是由裝置擁有者「<ph name="OWNER_EMAIL" />」管理。</translation> @@ -388,7 +384,6 @@ <translation id="1567387640189251553">自你上次輸入密碼後,裝置已連接其他鍵盤。你的按鍵行為可能會遭到側錄。</translation> <translation id="1567750922576943685">驗證你的身分有助於確保個人資訊安全無虞</translation> <translation id="1567993339577891801">JavaScript 控制台</translation> -<translation id="1568067597247500137">關閉網站音訊</translation> <translation id="1568323446248056064">開啟顯示裝置設定</translation> <translation id="1572266655485775982">啟用 Wi-Fi</translation> <translation id="1572585716423026576">設為桌布</translation> @@ -440,7 +435,6 @@ <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="1646982517418478057">請輸入加密這個憑證時所使用的密碼</translation> <translation id="164814987133974965">受監管的使用者可以依照你的指示瀏覽網路。受監管使用者的管理員可以: <ph name="BEGIN_BOLD" />允許或禁止<ph name="END_BOLD" />特定網站; @@ -499,7 +493,6 @@ <translation id="1729533290416704613">這個擴充功能也會控管你使用網址列搜尋時所顯示的網頁。</translation> <translation id="1730917990259790240"><ph name="BEGIN_PARAGRAPH1" />如要移除應用程式,請依序前往 [設定] > [Google Play 商店] > [管理 Android 偏好設定] > [應用程式] 或 [應用程式管理員],然後輕觸你要解除安裝的應用程式 (你可能需要向左或向右滑動才能找出應用程式)。接著,輕觸 [解除安裝] 或 [停用]。<ph name="END_PARAGRAPH1" /></translation> <translation id="1731911755844941020">正在傳送要求...</translation> -<translation id="1732215134274276513">取消固定分頁</translation> <translation id="1733383495376208985">使用你自己的<ph name="BEGIN_LINK" />同步通關密語<ph name="END_LINK" />,加密保護同步資料。這不包括 Google Pay 的付款方式和地址。</translation> <translation id="1734824808160898225">「<ph name="PRODUCT_NAME" />」可能無法自動更新</translation> <translation id="1736419249208073774">探索</translation> @@ -550,7 +543,6 @@ <translation id="1807938677607439181">所有檔案</translation> <translation id="1809734401532861917">將我的書籤、歷史記錄、密碼和其他設定新增至 <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="1810764548349082891">無法預覽</translation> -<translation id="1812631533912615985">取消固定分頁</translation> <translation id="1813278315230285598">服務</translation> <translation id="18139523105317219">EDI 合作對象名稱</translation> <translation id="1815083418640426271">以純文字貼上</translation> @@ -709,7 +701,6 @@ <translation id="2065405795449409761">Chrome 目前受到自動測試軟體控制。</translation> <translation id="2070909990982335904">以點號開頭的名稱僅供系統使用,請選擇其他名稱。</translation> <translation id="2071393345806050157">沒有本機記錄檔案。</translation> -<translation id="2074527029802029717">取消分頁固定</translation> <translation id="2075474481720804517">電量:<ph name="BATTERY_PERCENTAGE" />%</translation> <translation id="2075959085554270910">讓你啟用/停用輕觸點選和輕觸拖曳功能</translation> <translation id="2076269580855484719">隱藏這個外掛程式</translation> @@ -1347,7 +1338,6 @@ <translation id="3045447014237878114">這個網站已自動下載多個檔案</translation> <translation id="3046910703532196514">完整的網頁</translation> <translation id="304747341537320566">語音引擎</translation> -<translation id="304826556400666995">開啟多個分頁音訊</translation> <translation id="3053013834507634016">憑證金鑰用途</translation> <translation id="3057861065630527966">備份您的相片和影片</translation> <translation id="3060379269883947824">啟用隨選朗讀功能</translation> @@ -2322,7 +2312,6 @@ <translation id="4628762811416793313">無法完成 Linux 容器設定。請再試一次。</translation> <translation id="4628948037717959914">相片</translation> <translation id="4631887759990505102">演出者</translation> -<translation id="4632483769545853758">開啟分頁音訊</translation> <translation id="4633003931260532286">擴充功能要求的最低「<ph name="IMPORT_NAME" />」版本是「<ph name="IMPORT_VERSION" />」,但目前只安裝了版本「<ph name="INSTALLED_VERSION" />」</translation> <translation id="4634771451598206121">重新登入...</translation> <translation id="4635398712689569051">訪客使用者無法使用<ph name="PAGE_NAME" />。</translation> @@ -2386,7 +2375,6 @@ <translation id="4735803855089279419">系統無法判別這個裝置的裝置識別碼。</translation> <translation id="4737715515457435632">請連上網路</translation> <translation id="473775607612524610">更新</translation> -<translation id="474217410105706308">關閉分頁音訊</translation> <translation id="4742746985488890273">固定至檔案櫃</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />瞭解如何更新應用程式<ph name="END_LINK" /></translation> <translation id="4746351372139058112">Messages</translation> @@ -2611,7 +2599,6 @@ <translation id="5094721898978802975">與合作內建應用程式建立連線</translation> <translation id="5097002363526479830">無法連線至「<ph name="NAME" />」:<ph name="DETAILS" /></translation> <translation id="5101042277149003567">開啟所有書籤</translation> -<translation id="5105855035535475848">固定分頁</translation> <translation id="5108967062857032718">設定 - 移除 Android 應用程式</translation> <translation id="5109044022078737958">咪咪</translation> <translation id="5111692334209731439">書籤管理員(&B)</translation> @@ -2674,7 +2661,6 @@ <translation id="520621735928254154">憑證匯入錯誤</translation> <translation id="5209320130288484488">找不到裝置</translation> <translation id="5209518306177824490">SHA-1 指紋</translation> -<translation id="5210365745912300556">關閉分頁</translation> <translation id="5213481667492808996">現在可以使用「<ph name="NAME" />」的數據服務了</translation> <translation id="5213891612754844763">顯示 Proxy 設定</translation> <translation id="521582610500777512">已捨棄相片</translation> @@ -2724,7 +2710,6 @@ <translation id="5269977353971873915">列印失敗</translation> <translation id="5275352920323889391">狗</translation> <translation id="5275973617553375938">從 Google 雲端硬碟還原檔案</translation> -<translation id="527605719918376753">關閉分頁音訊</translation> <translation id="527605982717517565">永遠允許在 <ph name="HOST" /> 執行 JavaScript</translation> <translation id="5280426389926346830">要建立捷徑嗎?</translation> <translation id="528208740344463258">如要下載並使用 Android 應用程式,請先安裝這項必要更新。在 <ph name="DEVICE_TYPE" /> 更新期間,你無法使用裝置。安裝完成後,<ph name="DEVICE_TYPE" /> 將會重新啟動。</translation> @@ -2847,7 +2832,6 @@ <translation id="5449551289610225147">密碼無效</translation> <translation id="5449588825071916739">將所有分頁加入書籤</translation> <translation id="5449716055534515760">關閉視窗(&D)</translation> -<translation id="5453029940327926427">關閉分頁</translation> <translation id="5454166040603940656">提供者:<ph name="PROVIDER" /></translation> <translation id="5457113250005438886">無效</translation> <translation id="5457459357461771897">讀取及刪除你電腦中的相片、音樂及其他媒體</translation> @@ -3311,7 +3295,6 @@ <translation id="6122875415561139701">無法在以下裝置上執行寫入作業:「<ph name="DEVICE_NAME" />」。</translation> <translation id="6124650939968185064">下列擴充功能與這個擴充功能之間有相依關係:</translation> <translation id="6125479973208104919">很抱歉,你需要重新在 <ph name="DEVICE_TYPE" /> 上新增帳戶。</translation> -<translation id="612596694132302162">開啟網站音訊</translation> <translation id="6129691635767514872">系統已將所選資料從 Chrome 和其他同步的裝置中移除。你的 Google 帳戶仍可能保留了其他類型的瀏覽記錄,例如其他 Google 服務中的搜尋和活動記錄 (可前往 <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> 查詢)。</translation> <translation id="6129938384427316298">Netscape 憑證評論</translation> <translation id="6129953537138746214">空格</translation> @@ -3512,7 +3495,6 @@ <translation id="6436164536244065364">在線上應用程式商店中查看</translation> <translation id="6438992844451964465"><ph name="WINDOW_TITLE" /> - 音訊播放中</translation> <translation id="6442187272350399447">真正讚</translation> -<translation id="6442697326824312960">取消標籤固定</translation> <translation id="6444070574980481588">設定日期和時間</translation> <translation id="6445450263907939268">如果你不想套用這些變更,可以還原為先前的設定。</translation> <translation id="6447842834002726250">Cookie</translation> @@ -3715,7 +3697,6 @@ <translation id="6770664076092644100">透過 NFC 進行驗證</translation> <translation id="6771503742377376720">這是憑證授權單位</translation> <translation id="6777817260680419853">已禁止重新導向</translation> -<translation id="6778959797435875428">開啟多個網站音訊</translation> <translation id="677965093459947883">非常小</translation> <translation id="6780439250949340171">管理其他設定</translation> <translation id="6782111308708962316">禁止第三方網站儲存及讀取 Cookie 資料</translation> @@ -4028,7 +4009,6 @@ <translation id="7257666756905341374">讀取你複製和貼上的資料</translation> <translation id="7258697411818564379">PIN 碼新增成功</translation> <translation id="7262004276116528033">這是由 <ph name="SAML_DOMAIN" /> 代管的登入服務。</translation> -<translation id="7268365133021434339">關閉分頁</translation> <translation id="7268659760406822741">可用的服務</translation> <translation id="7270858098575133036">每當有網站要使用系統專用訊息存取 MIDI 裝置時詢問我</translation> <translation id="7272674038937250585">沒有任何說明</translation> @@ -4216,7 +4196,6 @@ <translation id="7576032389798113292">6x4</translation> <translation id="7576690715254076113">自動分頁</translation> <translation id="7576976045740938453">示範模式的帳戶發生問題。</translation> -<translation id="7579149537961810247">關閉多個網站音訊</translation> <translation id="7580671184200851182">透過所有喇叭播放相同的音效 (單聲道音訊)</translation> <translation id="7581462281756524039">清理工具</translation> <translation id="7582582252461552277">偏好使用這個網路</translation> @@ -4569,7 +4548,6 @@ <translation id="8068253693380742035">輕觸即可登入</translation> <translation id="8069615408251337349">Google 雲端列印</translation> <translation id="8071432093239591881">以圖片形式列印</translation> -<translation id="8072988827236813198">固定分頁</translation> <translation id="8073499153683482226"><ph name="BEGIN_PARAGRAPH1" />應用程式資料泛指應用程式依據開發人員設定所儲存的任何資料,包括聯絡人、訊息和相片等。<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />備份資料不會計入貴子女帳戶的雲端硬碟儲存空間配額。<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />你可以在「設定」中停用這項服務。<ph name="END_PARAGRAPH3" /></translation> @@ -4753,7 +4731,6 @@ <translation id="8368859634510605990">開啟所有書籤(&O)</translation> <translation id="8371695176452482769">請說話</translation> <translation id="8372369524088641025">WEP 金鑰有誤</translation> -<translation id="8373553483208508744">關閉多個分頁音訊</translation> <translation id="8378714024927312812">由貴機構管理</translation> <translation id="8379878387931047019">這部裝置不支援這個網站所要求的安全金鑰類型</translation> <translation id="8382913212082956454">複製電子郵件地址(&E)</translation> @@ -4860,7 +4837,6 @@ <translation id="8546930481464505581">自訂 Touch Bar</translation> <translation id="8547013269961688403">啟用全螢幕放大鏡</translation> <translation id="85486688517848470">按住搜尋鍵即可切換最上排按鍵的行為</translation> -<translation id="855081842937141170">固定分頁</translation> <translation id="8551388862522347954">授權</translation> <translation id="8553342806078037065">管理其他使用者</translation> <translation id="8554899698005018844">未指定語言</translation> @@ -5172,7 +5148,6 @@ <translation id="9038430547971207796">下次手機就會為你的 <ph name="DEVICE_TYPE" /> 解鎖。你可以在「設定」中停用 Smart Lock。</translation> <translation id="9038649477754266430">使用預測查詢字串服務,讓系統更快載入網頁</translation> <translation id="9039663905644212491">PEAP</translation> -<translation id="9039890312082871605">關閉多個分頁音訊</translation> <translation id="9040661932550800571">要更新 <ph name="ORIGIN" /> 的密碼嗎?</translation> <translation id="9041692268811217999">管理員停用了電腦本機檔案的存取權</translation> <translation id="9042893549633094279">隱私權和安全性</translation> @@ -5270,7 +5245,6 @@ <translation id="920045321358709304">透過 <ph name="SEARCH_ENGINE" /> 搜尋</translation> <translation id="9201220332032049474">螢幕鎖定選項</translation> <translation id="9203398526606335860">分析已啟用(&P)</translation> -<translation id="9203478404496196495">開啟分頁音訊</translation> <translation id="9203904171912129171">選取裝置</translation> <translation id="9203962528777363226">裝置管理員已停用新增使用者功能</translation> <translation id="9213073329713032541">已成功啟動安裝程序。</translation>
diff --git a/chrome/browser/android/cached_image_fetcher/cached_image_fetcher_bridge.cc b/chrome/browser/android/cached_image_fetcher/cached_image_fetcher_bridge.cc index 62558f3..22b20d5 100644 --- a/chrome/browser/android/cached_image_fetcher/cached_image_fetcher_bridge.cc +++ b/chrome/browser/android/cached_image_fetcher/cached_image_fetcher_bridge.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/cached_image_fetcher/cached_image_fetcher_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_android.h" +#include "components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter.h" #include "components/image_fetcher/core/cache/image_cache.h" #include "components/image_fetcher/core/cached_image_fetcher.h" #include "components/image_fetcher/core/cached_image_fetcher_service.h"
diff --git a/chrome/browser/android/feed/feed_logging_bridge.cc b/chrome/browser/android/feed/feed_logging_bridge.cc index d69d899..a2d4839 100644 --- a/chrome/browser/android/feed/feed_logging_bridge.cc +++ b/chrome/browser/android/feed/feed_logging_bridge.cc
@@ -108,9 +108,11 @@ void FeedLoggingBridge::OnOpenedWithContent(JNIEnv* j_env, const JavaRef<jobject>& j_this, - const jint j_time_to_Populate, + const jlong j_time_to_populate, const jint j_content_count) { feed_logging_metrics_->OnPageShown(j_content_count); + feed_logging_metrics_->OnPagePopulated( + base::TimeDelta::FromMilliseconds(j_time_to_populate)); } void FeedLoggingBridge::OnOpenedWithNoImmediateContent(
diff --git a/chrome/browser/android/feed/feed_logging_bridge.h b/chrome/browser/android/feed/feed_logging_bridge.h index c8c8e6b..3208cbd 100644 --- a/chrome/browser/android/feed/feed_logging_bridge.h +++ b/chrome/browser/android/feed/feed_logging_bridge.h
@@ -61,7 +61,7 @@ void OnOpenedWithContent(JNIEnv* j_env, const base::android::JavaRef<jobject>& j_this, - const jint j_time_to_Populate, + const jlong j_time_to_populate, const jint j_content_count); void OnOpenedWithNoImmediateContent(
diff --git a/chrome/browser/android/vr/vr_shell.cc b/chrome/browser/android/vr/vr_shell.cc index e25955d..8dc3df1 100644 --- a/chrome/browser/android/vr/vr_shell.cc +++ b/chrome/browser/android/vr/vr_shell.cc
@@ -319,11 +319,11 @@ // we need to block shutting down the GvrLayout on stopping our GL thread // from using the GvrApi instance. // base::Thread::Stop, which is called when destroying the thread, asserts - // that IO is allowed to prevent jank, but there shouldn't be any concerns - // regarding jank in this case, because we're switching from 3D to 2D, - // adding/removing a bunch of Java views, and probably changing device - // orientation here. - base::ThreadRestrictions::ScopedAllowIO allow_io; + // that sync primitives are allowed to prevent jank, but there shouldn't be + // any concerns regarding jank in this case, because we're switching from 3D + // to 2D, adding/removing a bunch of Java views, and probably changing + // device orientation here. + base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_thread_join; gl_thread_.reset(); } g_vr_shell_instance = nullptr;
diff --git a/chrome/browser/apps/app_service/dip_px_util.cc b/chrome/browser/apps/app_service/dip_px_util.cc index 48d5fe0e..e0511902 100644 --- a/chrome/browser/apps/app_service/dip_px_util.cc +++ b/chrome/browser/apps/app_service/dip_px_util.cc
@@ -12,7 +12,7 @@ namespace { -float GetDeviceScaleFactor() { +float GetPrimaryDisplayScaleFactor() { display::Screen* screen = display::Screen::GetScreen(); if (!screen) { return 1.0f; @@ -26,12 +26,12 @@ int ConvertDipToPx(int dip) { return base::saturated_cast<int>( - std::floor(static_cast<float>(dip) * GetDeviceScaleFactor())); + std::floor(static_cast<float>(dip) * GetPrimaryDisplayScaleFactor())); } int ConvertPxToDip(int px) { return base::saturated_cast<int>( - std::floor(static_cast<float>(px) / GetDeviceScaleFactor())); + std::floor(static_cast<float>(px) / GetPrimaryDisplayScaleFactor())); } } // namespace apps
diff --git a/chrome/browser/apps/app_shim/app_shim_interactive_uitest_mac.mm b/chrome/browser/apps/app_shim/app_shim_interactive_uitest_mac.mm index 4d4b343..0fcbfca9 100644 --- a/chrome/browser/apps/app_shim/app_shim_interactive_uitest_mac.mm +++ b/chrome/browser/apps/app_shim/app_shim_interactive_uitest_mac.mm
@@ -595,7 +595,8 @@ web_app::WebAppShortcutCreator shortcut_creator( web_app::GetWebAppDataDirectory(profile()->GetPath(), app->id(), GURL()), shortcut_info.get()); - shortcut_creator.UpdateShortcuts(); + std::vector<base::FilePath> updated_paths; + shortcut_creator.UpdateShortcuts(false, &updated_paths); base::FilePath shim_path = shortcut_creator.GetInternalShortcutPath(); NSMutableDictionary* plist_64 = [NSMutableDictionary dictionaryWithContentsOfFile:base::mac::FilePathToNSString(
diff --git a/chrome/browser/apps/app_shim/extension_app_shim_handler_mac.cc b/chrome/browser/apps/app_shim/extension_app_shim_handler_mac.cc index e17a11a..1d919a1 100644 --- a/chrome/browser/apps/app_shim/extension_app_shim_handler_mac.cc +++ b/chrome/browser/apps/app_shim/extension_app_shim_handler_mac.cc
@@ -252,9 +252,9 @@ Profile* profile, const Extension* extension, base::OnceCallback<void(base::Process)> launch_callback) { - web_app::MaybeLaunchShortcut( - web_app::ShortcutInfoForExtensionAndProfile(extension, profile), - std::move(launch_callback)); + web_app::LaunchShim( + web_app::LaunchShimUpdateBehavior::NO_UPDATE, std::move(launch_callback), + web_app::ShortcutInfoForExtensionAndProfile(extension, profile)); } void ExtensionAppShimHandler::Delegate::LaunchUserManager() {
diff --git a/chrome/browser/badging/badge_service_delegate.h b/chrome/browser/badging/badge_service_delegate.h index c7f0d0e..83962d07f 100644 --- a/chrome/browser/badging/badge_service_delegate.h +++ b/chrome/browser/badging/badge_service_delegate.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_BADGING_BADGE_SERVICE_DELEGATE_H_ #define CHROME_BROWSER_BADGING_BADGE_SERVICE_DELEGATE_H_ +#include "base/optional.h" + namespace content { class WebContents; } @@ -14,8 +16,8 @@ class BadgeServiceDelegate { public: // Sets the Badge for |web_contents|. - // TODO(harrisjay): Make this accept contents for the badge. - void SetBadge(content::WebContents* web_contents); + void SetBadge(content::WebContents* web_contents, + base::Optional<uint64_t> badge_content); // Clears the badge for |web_contents|. void ClearBadge(content::WebContents* web_contents);
diff --git a/chrome/browser/badging/badge_service_impl.cc b/chrome/browser/badging/badge_service_impl.cc index 56786ba..5972d703 100644 --- a/chrome/browser/badging/badge_service_impl.cc +++ b/chrome/browser/badging/badge_service_impl.cc
@@ -28,7 +28,15 @@ new BadgeServiceImpl(render_frame_host, std::move(request)); } -void BadgeServiceImpl::SetBadge() { +void BadgeServiceImpl::SetInteger(uint64_t content) { + SetBadge(base::Optional<uint64_t>(content)); +} + +void BadgeServiceImpl::SetFlag() { + SetBadge(base::nullopt); +} + +void BadgeServiceImpl::SetBadge(base::Optional<uint64_t> content) { #if defined(OS_CHROMEOS) const extensions::Extension* extension = ExtensionFromLastUrl(); @@ -40,7 +48,7 @@ if (!IsInApp()) return; - delegate_->SetBadge(web_contents_); + delegate_->SetBadge(web_contents_, content); #endif }
diff --git a/chrome/browser/badging/badge_service_impl.h b/chrome/browser/badging/badge_service_impl.h index 23402fc..69b757e 100644 --- a/chrome/browser/badging/badge_service_impl.h +++ b/chrome/browser/badging/badge_service_impl.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_BADGING_BADGE_SERVICE_IMPL_H_ #define CHROME_BROWSER_BADGING_BADGE_SERVICE_IMPL_H_ +#include "base/optional.h" #include "content/public/browser/frame_service_base.h" #include "third_party/blink/public/platform/modules/badging/badging.mojom.h" @@ -35,8 +36,8 @@ content::RenderFrameHost* render_frame_host); // blink::mojom::BadgeService overrides. - // TODO(crbug.com/719176): Support non-flag badges. - void SetBadge() override; + void SetInteger(uint64_t content) override; + void SetFlag() override; void ClearBadge() override; private: @@ -44,6 +45,7 @@ blink::mojom::BadgeServiceRequest request); ~BadgeServiceImpl() override; + void SetBadge(base::Optional<uint64_t> content); const extensions::Extension* ExtensionFromLastUrl(); bool IsInApp();
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 99249f0..ab9515d 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -245,6 +245,8 @@ <include name="IDR_APP_MANAGEMENT_PWA_PERMISSION_VIEW_JS" file="resources\app_management\pwa_permission_view.js" type="BINDATA"/> <include name="IDR_APP_MANAGEMENT_REDUCERS_HTML" file="resources\app_management\reducers.html" type="BINDATA" /> <include name="IDR_APP_MANAGEMENT_REDUCERS_JS" file="resources\app_management\reducers.js" type="BINDATA" /> + <include name="IDR_APP_MANAGEMENT_ROUTER_HTML" file="resources\app_management\router.html" type="BINDATA" /> + <include name="IDR_APP_MANAGEMENT_ROUTER_JS" file="resources\app_management\router.js" type="BINDATA" /> <include name="IDR_APP_MANAGEMENT_SHARED_STYLE_HTML" file="resources\app_management\shared_style.html" type="BINDATA"/> <include name="IDR_APP_MANAGEMENT_SHARED_VARS_HTML" file="resources\app_management\shared_vars.html" type="BINDATA"/> <include name="IDR_APP_MANAGEMENT_STORE_CLIENT_HTML" file="resources\app_management\store_client.html" type="BINDATA" /> @@ -316,18 +318,18 @@ <!-- MD History. --> <include name="IDR_MD_HISTORY_CONSTANTS_HTML" file="resources\md_history\constants.html" type="BINDATA" /> <include name="IDR_MD_HISTORY_CONSTANTS_JS" file="resources\md_history\constants.js" type="BINDATA" /> - <include name="IDR_MD_HISTORY_HISTORY_HTML" file="resources\md_history\history.html" flattenhtml="true" type="BINDATA" compress="gzip" /> + <include name="IDR_MD_HISTORY_HISTORY_HTML" file="resources\md_history\history.html" preprocess="true" type="BINDATA" compress="gzip" /> <include name="IDR_MD_HISTORY_HISTORY_JS" file="resources\md_history\history.js" type="BINDATA" /> <include name="IDR_MD_HISTORY_IMAGES_100_SIGN_IN_PROMO_JPG" file="resources\md_history\images\100\sign_in_promo.jpg" type="BINDATA" /> <include name="IDR_MD_HISTORY_IMAGES_200_SIGN_IN_PROMO_JPG" file="resources\md_history\images\200\sign_in_promo.jpg" type="BINDATA" /> <if expr="optimize_webui"> <then> - <include name="IDR_MD_HISTORY_APP_VULCANIZED_HTML" file="${root_gen_dir}\chrome\browser\resources\md_history\app.vulcanized.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" use_base_dir="false" /> - <include name="IDR_MD_HISTORY_APP_VULCANIZED_P2_HTML" file="${root_gen_dir}\chrome\browser\resources\md_history\app.vulcanized.p2.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" use_base_dir="false" /> - <include name="IDR_MD_HISTORY_APP_CRISPER_JS" file="${root_gen_dir}\chrome\browser\resources\md_history\app.crisper.js" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" use_base_dir="false" /> - <include name="IDR_MD_HISTORY_LAZY_LOAD_VULCANIZED_HTML" file="${root_gen_dir}\chrome\browser\resources\md_history\lazy_load.vulcanized.html" allowexternalscript="true" type="BINDATA" compress="gzip" use_base_dir="false" /> - <include name="IDR_MD_HISTORY_LAZY_LOAD_VULCANIZED_P2_HTML" file="${root_gen_dir}\chrome\browser\resources\md_history\lazy_load.vulcanized.p2.html" allowexternalscript="true" type="BINDATA" compress="gzip" use_base_dir="false" /> - <include name="IDR_MD_HISTORY_LAZY_LOAD_CRISPER_JS" file="${root_gen_dir}\chrome\browser\resources\md_history\lazy_load.crisper.js" allowexternalscript="true" type="BINDATA" compress="gzip" use_base_dir="false" /> + <include name="IDR_MD_HISTORY_APP_VULCANIZED_HTML" file="${root_gen_dir}\chrome\browser\resources\md_history\app.vulcanized.html" preprocess="true" type="BINDATA" compress="gzip" use_base_dir="false" /> + <include name="IDR_MD_HISTORY_APP_VULCANIZED_P2_HTML" file="${root_gen_dir}\chrome\browser\resources\md_history\app.vulcanized.p2.html" preprocess="true" type="BINDATA" compress="gzip" use_base_dir="false" /> + <include name="IDR_MD_HISTORY_APP_CRISPER_JS" file="${root_gen_dir}\chrome\browser\resources\md_history\app.crisper.js" preprocess="true" type="BINDATA" compress="gzip" use_base_dir="false" /> + <include name="IDR_MD_HISTORY_LAZY_LOAD_VULCANIZED_HTML" file="${root_gen_dir}\chrome\browser\resources\md_history\lazy_load.vulcanized.html" preprocess="true" type="BINDATA" compress="gzip" use_base_dir="false" /> + <include name="IDR_MD_HISTORY_LAZY_LOAD_VULCANIZED_P2_HTML" file="${root_gen_dir}\chrome\browser\resources\md_history\lazy_load.vulcanized.p2.html" preprocess="true" type="BINDATA" compress="gzip" use_base_dir="false" /> + <include name="IDR_MD_HISTORY_LAZY_LOAD_CRISPER_JS" file="${root_gen_dir}\chrome\browser\resources\md_history\lazy_load.crisper.js" preprocess="true" type="BINDATA" compress="gzip" use_base_dir="false" /> </then> <else> <include name="IDR_MD_HISTORY_APP_HTML" file="resources\md_history\app.html" type="BINDATA" />
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 3bb5f6d..d81a3c8 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -96,9 +96,6 @@ "//chromeos/components/proximity_auth", "//chromeos/components/tether", "//chromeos/network", - "//chromeos/services/device_sync", - "//chromeos/services/device_sync/proto", - "//chromeos/services/device_sync/proto:util", "//chromeos/services/device_sync/public/cpp", "//chromeos/services/machine_learning/public/cpp", "//chromeos/services/machine_learning/public/mojom",
diff --git a/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc b/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc index a389530..4a9458e 100644 --- a/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc +++ b/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc
@@ -35,7 +35,6 @@ #include "chrome/browser/supervised_user/supervised_user_constants.h" #include "chrome/browser/ui/app_list/arc/arc_data_removal_dialog.h" #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" -#include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/testing_profile.h" #include "chromeos/account_manager/account_manager.h" @@ -60,7 +59,6 @@ #include "components/signin/core/browser/account_tracker_service.h" #include "components/user_manager/scoped_user_manager.h" #include "components/user_manager/user_manager.h" -#include "components/user_manager/user_names.h" #include "content/public/browser/browser_task_traits.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" @@ -265,6 +263,9 @@ identity_test_environment_adaptor_->identity_test_env(); identity_test_env->SetAutomaticIssueOfAccessTokens(true); identity_test_env->MakePrimaryAccountAvailable(kFakeUserName); + identity_test_env->identity_manager() + ->GetAccountsMutator() + ->LoadAccountsFromDisk(kFakeUserName); profile()->GetPrefs()->SetBoolean(prefs::kArcSignedIn, true); profile()->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, true); @@ -468,19 +469,6 @@ ArcAuthServiceTest::SetUp(); } - void SetUpCommandLine(base::CommandLine* command_line) override { - // Configure primary profile to be a guest profile, because the - // AccountManager can't deal with regular profiles in tests. - // https://crbug.com/915628 - command_line->AppendSwitch(chromeos::switches::kGuestSession); - command_line->AppendSwitch(switches::kIncognito); - command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "hash"); - command_line->AppendSwitchASCII( - chromeos::switches::kLoginUser, - user_manager::GuestAccountId().GetUserEmail()); - ArcAuthServiceTest::SetUpCommandLine(command_line); - } - AccountInfo SetupGaiaAccount(const std::string& email, const std::string& token) { SetAccountAndProfile(user_manager::USER_TYPE_REGULAR);
diff --git a/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.cc b/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.cc index 21e8e94e..613695b 100644 --- a/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.cc +++ b/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.cc
@@ -1009,7 +1009,7 @@ void ArcBluetoothBridge::SetDiscoverable(bool discoverable, uint32_t timeout) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(bluetooth_adapter_); - DCHECK(!discoverable || timeout == 0); + DCHECK(!discoverable || timeout != 0); bool currently_discoverable = bluetooth_adapter_->IsDiscoverable();
diff --git a/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.cc b/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.cc index ff36e20..1201097 100644 --- a/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.cc +++ b/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.cc
@@ -23,6 +23,7 @@ #include "chrome/browser/notifications/notification_display_service.h" #include "chrome/browser/notifications/notification_display_service_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/common/pref_names.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" @@ -36,6 +37,7 @@ #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/signin/core/browser/profile_oauth2_token_service.h" #include "dbus/message.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" @@ -91,7 +93,7 @@ return adjusted_config; } -// Sets up Chrome OS Account Manager. +// Sets up Chrome OS Account Manager and starts |ProfileOAuth2TokenService|. // |profile| is a non-owning pointer to |Profile|. // |object_guid| is the Active Directory Object GUID for the Device Account. void SetupAccountManager(Profile* profile, const std::string& object_guid) { @@ -111,6 +113,11 @@ object_guid, account_manager::AccountType::ACCOUNT_TYPE_ACTIVE_DIRECTORY}, AccountManager::kActiveDirectoryDummyToken); + + // Needed to work with Secondary Accounts in Chrome OS Account Manager. The + // value of |primary_account_id| doesn't matter. + ProfileOAuth2TokenServiceFactory::GetForProfile(profile)->LoadCredentials( + std::string() /* primary_account_id */); } } // namespace @@ -406,6 +413,7 @@ : BrowserContextKeyedServiceFactory( "AuthPolicyCredentialsManager", BrowserContextDependencyManager::GetInstance()) { + DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance()); } AuthPolicyCredentialsManagerFactory::~AuthPolicyCredentialsManagerFactory() {}
diff --git a/chrome/browser/chromeos/crostini/crostini_package_notification.cc b/chrome/browser/chromeos/crostini/crostini_package_notification.cc index 4746209..6927981 100644 --- a/chrome/browser/chromeos/crostini/crostini_package_notification.cc +++ b/chrome/browser/chromeos/crostini/crostini_package_notification.cc
@@ -43,6 +43,7 @@ notification_settings_( GetNotificationSettingsForTypeAndAppName(notification_type, app_name)), + visible_(true), weak_ptr_factory_(this) { if (status == PackageOperationStatus::RUNNING) { running_start_time_ = base::Time::Now(); @@ -217,11 +218,33 @@ } void CrostiniPackageNotification::Close(bool by_user) { - // This call deletes us. - package_service_->NotificationClosed(this); + if (current_status_ == PackageOperationStatus::RUNNING || + current_status_ == PackageOperationStatus::QUEUED) { + // We don't want to delete ourselves yet; we want to forcibly redisplay + // when we hit success or failure. Just note that we are hidden. + visible_ = false; + } else { + // This call deletes us. + package_service_->NotificationCompleted(this); + } } void CrostiniPackageNotification::UpdateDisplayedNotification() { + if (current_status_ == PackageOperationStatus::SUCCEEDED || + current_status_ == PackageOperationStatus::FAILED) { + // If the user closes the notification when it is queued or running, we + // still want to tell them when it is actually finished. So force the + // notification back to visibility when we get our success / fail notice. + // Note that we only get one success / fail notice, so we won't keep + // reshowing this. + visible_ = true; + } + + if (!visible_) { + // User hid, don't re-display. + return; + } + NotificationDisplayService* display_service = NotificationDisplayService::GetForProfile(profile_); display_service->Display(NotificationHandler::Type::TRANSIENT,
diff --git a/chrome/browser/chromeos/crostini/crostini_package_notification.h b/chrome/browser/chromeos/crostini/crostini_package_notification.h index f94f3d99..c36c6b6 100644 --- a/chrome/browser/chromeos/crostini/crostini_package_notification.h +++ b/chrome/browser/chromeos/crostini/crostini_package_notification.h
@@ -88,6 +88,9 @@ std::unique_ptr<message_center::Notification> notification_; + // True if we think the notification is visible. + bool visible_; + base::WeakPtrFactory<CrostiniPackageNotification> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(CrostiniPackageNotification);
diff --git a/chrome/browser/chromeos/crostini/crostini_package_service.cc b/chrome/browser/chromeos/crostini/crostini_package_service.cc index 615dbd1..ac83c31 100644 --- a/chrome/browser/chromeos/crostini/crostini_package_service.cc +++ b/chrome/browser/chromeos/crostini/crostini_package_service.cc
@@ -116,16 +116,8 @@ manager->RemoveLinuxPackageOperationProgressObserver(this); } -void CrostiniPackageService::NotificationClosed( +void CrostiniPackageService::NotificationCompleted( CrostiniPackageNotification* notification) { - for (auto it = running_notifications_.begin(); - it != running_notifications_.end(); ++it) { - if (it->second.get() == notification) { - running_notifications_.erase(it); - return; - } - } - for (auto it = finished_notifications_.begin(); it != finished_notifications_.end(); ++it) { if (it->get() == notification) { @@ -133,19 +125,7 @@ return; } } - - for (auto it = queued_uninstalls_.begin(); it != queued_uninstalls_.end(); - ++it) { - std::deque<QueuedUninstall>& queue = it->second; - for (auto it2 = queue.begin(); it2 != queue.end(); ++it2) { - if (it2->notification.get() == notification) { - // We need to delete the notification, but we still want to run the - // uninstall, so don't do erase(it2). - it2->notification.reset(); - return; - } - } - } + // Notifications should never delete themselves while queued or running. NOTREACHED(); } @@ -220,7 +200,6 @@ container_id, CrostiniPackageNotification::NotificationType::APPLICATION_UNINSTALL, app_name); - containers_with_running_operations_.insert(container_id); UninstallApplication(*registration, app_id); } @@ -233,8 +212,8 @@ bool CrostiniPackageService::ContainerHasRunningOperation( const ContainerIdentifier& container_id) const { - return containers_with_running_operations_.find(container_id) != - containers_with_running_operations_.end(); + return running_notifications_.find(container_id) != + running_notifications_.end(); } void CrostiniPackageService::CreateRunningNotification( @@ -265,7 +244,7 @@ const ContainerIdentifier& container_id, const std::string& app_id, const std::string& app_name) { - queued_uninstalls_[container_id].emplace_back( + queued_uninstalls_[container_id].emplace( app_id, std::make_unique<CrostiniPackageNotification>( profile_, @@ -278,33 +257,24 @@ const ContainerIdentifier& container_id, PackageOperationStatus status, int progress_percent) { - // Update the notification window, if any. User may have closed it while it - // was in progress, so don't complain if not found. + // Update the notification window, if any. auto it = running_notifications_.find(container_id); - if (it != running_notifications_.end()) { - DCHECK(it->second) << ContainerIdentifierToString(container_id) - << " has null notification pointer"; - it->second->UpdateProgress(status, progress_percent); + DCHECK(it != running_notifications_.end()) + << ContainerIdentifierToString(container_id) + << " has no notification to update"; + DCHECK(it->second) << ContainerIdentifierToString(container_id) + << " has null notification pointer"; + it->second->UpdateProgress(status, progress_percent); - if (status == PackageOperationStatus::SUCCEEDED || - status == PackageOperationStatus::FAILED) { - finished_notifications_.emplace_back(std::move(it->second)); - running_notifications_.erase(it); - } - } - - // Update our state and kick off the next operation if we just finished an - // operation. - DCHECK(ContainerHasRunningOperation(container_id)) - << "containers_with_running_operations_[" - << ContainerIdentifierToString(container_id) << "] not found"; if (status == PackageOperationStatus::SUCCEEDED || status == PackageOperationStatus::FAILED) { + finished_notifications_.emplace_back(std::move(it->second)); + running_notifications_.erase(it); + + // Kick off the next operation if we just finished one. auto queued_iter = queued_uninstalls_.find(container_id); - if (queued_iter == queued_uninstalls_.end() || - queued_iter->second.empty()) { - containers_with_running_operations_.erase(container_id); - } else { + if (queued_iter != queued_uninstalls_.end() && + !queued_iter->second.empty()) { StartQueuedUninstall(container_id); } } @@ -331,7 +301,6 @@ container_id, CrostiniPackageNotification::NotificationType::PACKAGE_INSTALL, "" /* app_name */); - containers_with_running_operations_.insert(container_id); } void CrostiniPackageService::UninstallApplication( @@ -397,24 +366,16 @@ if (uninstall_queue_iter == queued_uninstalls_.end()) { return; } - std::deque<QueuedUninstall>& uninstall_queue = uninstall_queue_iter->second; - { // Scope |next|; it becomes an invalid reference when we pop_front() + std::queue<QueuedUninstall>& uninstall_queue = uninstall_queue_iter->second; + { // Scope |next|; it becomes an invalid reference when we pop() QueuedUninstall& next = uninstall_queue.front(); - // User may have closed notification while still queued; don't complain if - // notification is nullptr. - if (next.notification) { - next.notification->UpdateProgress(PackageOperationStatus::RUNNING, 0); - running_notifications_.emplace(container_id, - std::move(next.notification)); - } + next.notification->UpdateProgress(PackageOperationStatus::RUNNING, 0); + running_notifications_.emplace(container_id, std::move(next.notification)); app_id = next.app_id; - uninstall_queue.pop_front(); // Invalidates |next| + uninstall_queue.pop(); // Invalidates |next| } - // containers_with_running_operations_ should be set from before and not - // cleared. - DCHECK(ContainerHasRunningOperation(container_id)); auto registration = CrostiniRegistryServiceFactory::GetForProfile(profile_)->GetRegistration(
diff --git a/chrome/browser/chromeos/crostini/crostini_package_service.h b/chrome/browser/chromeos/crostini/crostini_package_service.h index 7c24538e..749e5ad 100644 --- a/chrome/browser/chromeos/crostini/crostini_package_service.h +++ b/chrome/browser/chromeos/crostini/crostini_package_service.h
@@ -5,10 +5,9 @@ #ifndef CHROME_BROWSER_CHROMEOS_CROSTINI_CROSTINI_PACKAGE_SERVICE_H_ #define CHROME_BROWSER_CHROMEOS_CROSTINI_CROSTINI_PACKAGE_SERVICE_H_ -#include <deque> #include <map> #include <memory> -#include <set> +#include <queue> #include <string> #include <utility> #include <vector> @@ -33,7 +32,7 @@ // KeyedService: void Shutdown() override; - void NotificationClosed(CrostiniPackageNotification* notification); + void NotificationCompleted(CrostiniPackageNotification* notification); // The package installer service caches the most recent retrieved package // info, for use in a package install notification. @@ -148,15 +147,8 @@ std::map<ContainerIdentifier, std::unique_ptr<CrostiniPackageNotification>> running_notifications_; - // A list of containers with running operations. Generally, matches the list - // of containers with notifications, but we need a separate copy of the state - // in case the user closes the notification while still running. - std::set<ContainerIdentifier> containers_with_running_operations_; - - // Uninstalls we want to run when the current one is done. Operations are - // queued in FIFO order (but we can't use std::queue because we sometimes need - // to erase a notification window pointer in the middle of the queue). - std::map<ContainerIdentifier, std::deque<QueuedUninstall>> queued_uninstalls_; + // Uninstalls we want to run when the current one is done. + std::map<ContainerIdentifier, std::queue<QueuedUninstall>> queued_uninstalls_; // Notifications in a finished state (either SUCCEEDED or FAILED). We need // to keep notifications around until they are dismissed even if we don't
diff --git a/chrome/browser/chromeos/cryptauth/chrome_cryptauth_service.cc b/chrome/browser/chromeos/cryptauth/chrome_cryptauth_service.cc deleted file mode 100644 index 86c3d6a..0000000 --- a/chrome/browser/chromeos/cryptauth/chrome_cryptauth_service.cc +++ /dev/null
@@ -1,238 +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/cryptauth/chrome_cryptauth_service.h" - -#include "base/guid.h" -#include "base/linux_util.h" -#include "base/memory/ptr_util.h" -#include "base/system/sys_info.h" -#include "base/time/default_clock.h" -#include "base/version.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_content_browser_client.h" -#include "chrome/browser/chromeos/cryptauth/cryptauth_device_id_provider_impl.h" -#include "chrome/browser/chromeos/cryptauth/gcm_device_info_provider_impl.h" -#include "chrome/browser/gcm/gcm_profile_service_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/identity_manager_factory.h" -#include "chrome/common/pref_names.h" -#include "chromeos/components/multidevice/logging/logging.h" -#include "chromeos/components/multidevice/secure_message_delegate_impl.h" -#include "chromeos/services/device_sync/cryptauth_client.h" -#include "chromeos/services/device_sync/cryptauth_client_impl.h" -#include "chromeos/services/device_sync/cryptauth_device_manager_impl.h" -#include "chromeos/services/device_sync/cryptauth_enroller.h" -#include "chromeos/services/device_sync/cryptauth_enroller_impl.h" -#include "chromeos/services/device_sync/cryptauth_enrollment_manager_impl.h" -#include "chromeos/services/device_sync/cryptauth_gcm_manager_impl.h" -#include "chromeos/services/device_sync/proto/cryptauth_api.pb.h" -#include "chromeos/services/device_sync/proto/device_classifier_util.h" -#include "chromeos/services/multidevice_setup/public/cpp/prefs.h" -#include "components/gcm_driver/gcm_profile_service.h" -#include "components/prefs/pref_service.h" -#include "components/translate/core/browser/translate_download_manager.h" -#include "components/version_info/version_info.h" -#include "ui/gfx/geometry/rect.h" - -namespace chromeos { - -namespace { - -std::unique_ptr<device_sync::CryptAuthClientFactory> -CreateCryptAuthClientFactoryImpl(Profile* profile) { - return std::make_unique<device_sync::CryptAuthClientFactoryImpl>( - IdentityManagerFactory::GetForProfile(profile), - profile->GetURLLoaderFactory(), - device_sync::device_classifier_util::GetDeviceClassifier()); -} - -class CryptAuthEnrollerFactoryImpl - : public device_sync::CryptAuthEnrollerFactory { - public: - explicit CryptAuthEnrollerFactoryImpl( - device_sync::CryptAuthClientFactory* client_factory) - : client_factory_(client_factory) {} - - std::unique_ptr<device_sync::CryptAuthEnroller> CreateInstance() override { - return std::make_unique<device_sync::CryptAuthEnrollerImpl>( - client_factory_, - multidevice::SecureMessageDelegateImpl::Factory::NewInstance()); - } - - private: - device_sync::CryptAuthClientFactory* client_factory_; -}; - -} // namespace - -// static -std::unique_ptr<ChromeCryptAuthService> ChromeCryptAuthService::Create( - Profile* profile) { - std::unique_ptr<device_sync::CryptAuthClientFactory> client_factory = - CreateCryptAuthClientFactoryImpl(profile); - - std::unique_ptr<device_sync::CryptAuthGCMManager> gcm_manager = - device_sync::CryptAuthGCMManagerImpl::Factory::NewInstance( - gcm::GCMProfileServiceFactory::GetForProfile(profile)->driver(), - profile->GetPrefs()); - - std::unique_ptr<device_sync::CryptAuthDeviceManager> device_manager = - device_sync::CryptAuthDeviceManagerImpl::Factory::NewInstance( - base::DefaultClock::GetInstance(), client_factory.get(), - gcm_manager.get(), profile->GetPrefs()); - - std::unique_ptr<device_sync::CryptAuthEnrollmentManager> enrollment_manager = - device_sync::CryptAuthEnrollmentManagerImpl::Factory::NewInstance( - base::DefaultClock::GetInstance(), - std::make_unique<CryptAuthEnrollerFactoryImpl>(client_factory.get()), - multidevice::SecureMessageDelegateImpl::Factory::NewInstance(), - GcmDeviceInfoProviderImpl::GetInstance()->GetGcmDeviceInfo(), - gcm_manager.get(), profile->GetPrefs()); - - // Note: ChromeCryptAuthServiceFactory DependsOn(IdentityManagerFactory), - // so |identity_manager| is guaranteed to outlast this service. - identity::IdentityManager* identity_manager = - IdentityManagerFactory::GetForProfile(profile); - - return base::WrapUnique(new ChromeCryptAuthService( - std::move(client_factory), std::move(gcm_manager), - std::move(device_manager), std::move(enrollment_manager), profile, - identity_manager)); -} - -ChromeCryptAuthService::ChromeCryptAuthService( - std::unique_ptr<device_sync::CryptAuthClientFactory> client_factory, - std::unique_ptr<device_sync::CryptAuthGCMManager> gcm_manager, - std::unique_ptr<device_sync::CryptAuthDeviceManager> device_manager, - std::unique_ptr<device_sync::CryptAuthEnrollmentManager> enrollment_manager, - Profile* profile, - identity::IdentityManager* identity_manager) - : KeyedService(), - cryptauth::CryptAuthService(), - client_factory_(std::move(client_factory)), - gcm_manager_(std::move(gcm_manager)), - enrollment_manager_(std::move(enrollment_manager)), - device_manager_(std::move(device_manager)), - profile_(profile), - identity_manager_(identity_manager), - weak_ptr_factory_(this) { - gcm_manager_->StartListening(); - - registrar_.Init(profile_->GetPrefs()); - registrar_.Add(multidevice_setup::kSmartLockAllowedPrefName, - base::Bind(&ChromeCryptAuthService::OnPrefsChanged, - weak_ptr_factory_.GetWeakPtr())); - registrar_.Add(multidevice_setup::kInstantTetheringAllowedPrefName, - base::Bind(&ChromeCryptAuthService::OnPrefsChanged, - weak_ptr_factory_.GetWeakPtr())); - - if (!identity_manager_->HasPrimaryAccountWithRefreshToken()) { - PA_LOG(VERBOSE) << "Primary account with refresh token not yet available; " - << "waiting before starting CryptAuth managers."; - identity_manager_->AddObserver(this); - return; - } - - // Profile is authenticated and there is a refresh token available for the - // authenticated account id. - PerformEnrollmentAndDeviceSyncIfPossible(); -} - -ChromeCryptAuthService::~ChromeCryptAuthService() {} - -void ChromeCryptAuthService::Shutdown() { - identity_manager_->RemoveObserver(this); - enrollment_manager_.reset(); - device_manager_.reset(); - gcm_manager_.reset(); -} - -device_sync::CryptAuthDeviceManager* -ChromeCryptAuthService::GetCryptAuthDeviceManager() { - return device_manager_.get(); -} - -device_sync::CryptAuthEnrollmentManager* -ChromeCryptAuthService::GetCryptAuthEnrollmentManager() { - return enrollment_manager_.get(); -} - -cryptauth::DeviceClassifier ChromeCryptAuthService::GetDeviceClassifier() { - return device_sync::device_classifier_util::GetDeviceClassifier(); -} - -std::string ChromeCryptAuthService::GetAccountId() { - return identity_manager_->GetPrimaryAccountId(); -} - -std::unique_ptr<device_sync::CryptAuthClientFactory> -ChromeCryptAuthService::CreateCryptAuthClientFactory() { - return CreateCryptAuthClientFactoryImpl(profile_); -} - -void ChromeCryptAuthService::OnEnrollmentFinished(bool success) { - if (success) - device_manager_->Start(); - else - PA_LOG(ERROR) << "CryptAuth enrollment failed. Device manager was not " - << " started."; - - enrollment_manager_->RemoveObserver(this); -} - -void ChromeCryptAuthService::OnAuthenticationStateChanged() { - if (!identity_manager_->HasPrimaryAccountWithRefreshToken()) { - PA_LOG(VERBOSE) << "Primary account with refresh token not yet available; " - << "waiting before starting CryptAuth managers."; - return; - } - - identity_manager_->RemoveObserver(this); - PerformEnrollmentAndDeviceSyncIfPossible(); -} - -void ChromeCryptAuthService::OnPrimaryAccountSet( - const AccountInfo& primary_account_info) { - OnAuthenticationStateChanged(); -} - -void ChromeCryptAuthService::OnRefreshTokenUpdatedForAccount( - const AccountInfo& account_info) { - OnAuthenticationStateChanged(); -} - -void ChromeCryptAuthService::PerformEnrollmentAndDeviceSyncIfPossible() { - DCHECK(identity_manager_->HasPrimaryAccountWithRefreshToken()); - - // CryptAuth enrollment is allowed only if at least one multi-device feature - // is enabled. This ensures that we do not unnecessarily register devices on - // the CryptAuth back-end when the registration would never actually be used. - if (!multidevice_setup::AreAnyMultiDeviceFeaturesAllowed( - profile_->GetPrefs())) { - PA_LOG(VERBOSE) << "CryptAuth enrollment is disabled by enterprise policy."; - return; - } - - if (enrollment_manager_->IsEnrollmentValid()) { - device_manager_->Start(); - } else { - // If enrollment is not valid, wait for the new enrollment attempt to finish - // before starting CryptAuthDeviceManager. See OnEnrollmentFinished(), - enrollment_manager_->AddObserver(this); - } - - // Even if enrollment was valid, CryptAuthEnrollmentManager must be started in - // order to schedule the next enrollment attempt. - enrollment_manager_->Start(); -} - -void ChromeCryptAuthService::OnPrefsChanged() { - // Note: We only start the CryptAuth services if a feature was toggled on. In - // the inverse case, we simply leave the services running until the user logs - // off. - PerformEnrollmentAndDeviceSyncIfPossible(); -} - -} // namespace chromeos
diff --git a/chrome/browser/chromeos/cryptauth/chrome_cryptauth_service.h b/chrome/browser/chromeos/cryptauth/chrome_cryptauth_service.h deleted file mode 100644 index c032ccb..0000000 --- a/chrome/browser/chromeos/cryptauth/chrome_cryptauth_service.h +++ /dev/null
@@ -1,89 +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_CRYPTAUTH_CHROME_CRYPTAUTH_SERVICE_H_ -#define CHROME_BROWSER_CHROMEOS_CRYPTAUTH_CHROME_CRYPTAUTH_SERVICE_H_ - -#include <memory> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "chromeos/services/device_sync/cryptauth_enrollment_manager.h" -#include "chromeos/services/device_sync/proto/cryptauth_api.pb.h" -#include "components/cryptauth/cryptauth_service.h" -#include "components/keyed_service/core/keyed_service.h" -#include "components/prefs/pref_change_registrar.h" -#include "services/identity/public/cpp/identity_manager.h" - -class Profile; - -namespace chromeos { - -namespace device_sync { -class CryptAuthGCMManager; -} // namespace device_sync - -// Implementation of cryptauth::CryptAuthService. -class ChromeCryptAuthService - : public KeyedService, - public cryptauth::CryptAuthService, - public device_sync::CryptAuthEnrollmentManager::Observer, - public identity::IdentityManager::Observer { - public: - static std::unique_ptr<ChromeCryptAuthService> Create(Profile* profile); - ~ChromeCryptAuthService() override; - - // KeyedService: - void Shutdown() override; - - // cryptauth::CryptAuthService: - device_sync::CryptAuthDeviceManager* GetCryptAuthDeviceManager() override; - device_sync::CryptAuthEnrollmentManager* GetCryptAuthEnrollmentManager() - override; - cryptauth::DeviceClassifier GetDeviceClassifier() override; - std::string GetAccountId() override; - std::unique_ptr<device_sync::CryptAuthClientFactory> - CreateCryptAuthClientFactory() override; - - // device_sync::CryptAuthEnrollmentManager::Observer: - void OnEnrollmentFinished(bool success) override; - - protected: - // Note: ChromeCryptAuthServiceFactory DependsOn(OAuth2TokenServiceFactory), - // so |token_service| is guaranteed to outlast this service. - ChromeCryptAuthService( - std::unique_ptr<device_sync::CryptAuthClientFactory> client_factory, - std::unique_ptr<device_sync::CryptAuthGCMManager> gcm_manager, - std::unique_ptr<device_sync::CryptAuthDeviceManager> device_manager, - std::unique_ptr<device_sync::CryptAuthEnrollmentManager> - enrollment_manager, - Profile* profile, - identity::IdentityManager* identity_manager); - - private: - // identity::IdentityManager::Observer: - void OnPrimaryAccountSet(const AccountInfo& primary_account_info) override; - void OnRefreshTokenUpdatedForAccount( - const AccountInfo& account_info) override; - - void OnAuthenticationStateChanged(); - void PerformEnrollmentAndDeviceSyncIfPossible(); - void OnPrefsChanged(); - - std::unique_ptr<device_sync::CryptAuthClientFactory> client_factory_; - std::unique_ptr<device_sync::CryptAuthGCMManager> gcm_manager_; - std::unique_ptr<device_sync::CryptAuthEnrollmentManager> enrollment_manager_; - std::unique_ptr<device_sync::CryptAuthDeviceManager> device_manager_; - Profile* profile_; - identity::IdentityManager* identity_manager_; - PrefChangeRegistrar registrar_; - - base::WeakPtrFactory<ChromeCryptAuthService> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(ChromeCryptAuthService); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_CRYPTAUTH_CHROME_CRYPTAUTH_SERVICE_H_
diff --git a/chrome/browser/chromeos/cryptauth/chrome_cryptauth_service_factory.cc b/chrome/browser/chromeos/cryptauth/chrome_cryptauth_service_factory.cc deleted file mode 100644 index 56d04d5..0000000 --- a/chrome/browser/chromeos/cryptauth/chrome_cryptauth_service_factory.cc +++ /dev/null
@@ -1,49 +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/cryptauth/chrome_cryptauth_service_factory.h" - -#include "chrome/browser/chromeos/cryptauth/chrome_cryptauth_service.h" -#include "chrome/browser/gcm/gcm_profile_service_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/identity_manager_factory.h" -#include "chromeos/chromeos_features.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/pref_registry/pref_registry_syncable.h" - -namespace chromeos { - -// static -cryptauth::CryptAuthService* -ChromeCryptAuthServiceFactory::GetForBrowserContext( - content::BrowserContext* context) { - return static_cast<ChromeCryptAuthService*>( - GetInstance()->GetServiceForBrowserContext(context, true)); -} - -// static -ChromeCryptAuthServiceFactory* ChromeCryptAuthServiceFactory::GetInstance() { - return base::Singleton<ChromeCryptAuthServiceFactory>::get(); -} - -ChromeCryptAuthServiceFactory::ChromeCryptAuthServiceFactory() - : BrowserContextKeyedServiceFactory( - "CryptAuthService", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(IdentityManagerFactory::GetInstance()); - DependsOn(gcm::GCMProfileServiceFactory::GetInstance()); -} - -ChromeCryptAuthServiceFactory::~ChromeCryptAuthServiceFactory() {} - -KeyedService* ChromeCryptAuthServiceFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { - // TODO(hsuregan): This function, along with this class will be removed. - return nullptr; -} - -void ChromeCryptAuthServiceFactory::RegisterProfilePrefs( - user_prefs::PrefRegistrySyncable* registry) {} - -} // namespace chromeos
diff --git a/chrome/browser/chromeos/cryptauth/chrome_cryptauth_service_factory.h b/chrome/browser/chromeos/cryptauth/chrome_cryptauth_service_factory.h deleted file mode 100644 index a1775dd..0000000 --- a/chrome/browser/chromeos/cryptauth/chrome_cryptauth_service_factory.h +++ /dev/null
@@ -1,41 +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_CRYPTAUTH_CHROME_CRYPTAUTH_SERVICE_FACTORY_H_ -#define CHROME_BROWSER_CHROMEOS_CRYPTAUTH_CHROME_CRYPTAUTH_SERVICE_FACTORY_H_ - -#include "base/macros.h" -#include "base/memory/singleton.h" -#include "components/cryptauth/cryptauth_service.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace chromeos { - -// TODO(hsuregan): Remove this class. -// Factory which is used to access the CryptAuthService singleton. -class ChromeCryptAuthServiceFactory : public BrowserContextKeyedServiceFactory { - public: - static cryptauth::CryptAuthService* GetForBrowserContext( - content::BrowserContext* context); - - static ChromeCryptAuthServiceFactory* GetInstance(); - - private: - friend struct base::DefaultSingletonTraits<ChromeCryptAuthServiceFactory>; - - ChromeCryptAuthServiceFactory(); - ~ChromeCryptAuthServiceFactory() override; - - // BrowserContextKeyedServiceFactory - KeyedService* BuildServiceInstanceFor( - content::BrowserContext* context) const override; - void RegisterProfilePrefs( - user_prefs::PrefRegistrySyncable* registry) override; - - DISALLOW_COPY_AND_ASSIGN(ChromeCryptAuthServiceFactory); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_CRYPTAUTH_CHROME_CRYPTAUTH_SERVICE_FACTORY_H_
diff --git a/chrome/browser/chromeos/dbus/chrome_features_service_provider.cc b/chrome/browser/chromeos/dbus/chrome_features_service_provider.cc index d8bdc22..1d5f0de 100644 --- a/chrome/browser/chromeos/dbus/chrome_features_service_provider.cc +++ b/chrome/browser/chromeos/dbus/chrome_features_service_provider.cc
@@ -29,6 +29,26 @@ writer.AppendBool(answer); response_sender.Run(std::move(response)); } + +Profile* GetSenderProfile( + dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + dbus::MessageReader reader(method_call); + std::string user_id_hash; + + if (!reader.PopString(&user_id_hash)) { + LOG(ERROR) << "Failed to pop user_id_hash from incoming message."; + response_sender.Run(dbus::ErrorResponse::FromMethodCall( + method_call, DBUS_ERROR_INVALID_ARGS, "No user_id_hash string arg")); + return nullptr; + } + + if (user_id_hash.empty()) + return ProfileManager::GetActiveUserProfile(); + + return g_browser_process->profile_manager()->GetProfileByPath( + chromeos::ProfileHelper::GetProfilePathByUserIdHash(user_id_hash)); +} } // namespace namespace chromeos { @@ -83,24 +103,10 @@ void ChromeFeaturesServiceProvider::IsCrostiniEnabled( dbus::MethodCall* method_call, dbus::ExportedObject::ResponseSender response_sender) { - dbus::MessageReader reader(method_call); - std::string user_id_hash; - - if (!reader.PopString(&user_id_hash)) { - LOG(ERROR) << "Failed to pop user_id_hash from incoming message."; - response_sender.Run(dbus::ErrorResponse::FromMethodCall( - method_call, DBUS_ERROR_INVALID_ARGS, "No user_id_hash string arg")); - return; - } - - Profile* profile = - user_id_hash.empty() - ? ProfileManager::GetActiveUserProfile() - : g_browser_process->profile_manager()->GetProfileByPath( - ProfileHelper::GetProfilePathByUserIdHash(user_id_hash)); - - SendResponse(method_call, response_sender, - crostini::IsCrostiniAllowedForProfile(profile)); + Profile* profile = GetSenderProfile(method_call, response_sender); + SendResponse( + method_call, response_sender, + profile ? crostini::IsCrostiniAllowedForProfile(profile) : false); } void ChromeFeaturesServiceProvider::IsPluginVmEnabled(
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc index 1199f39..495d18b 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
@@ -1135,7 +1135,8 @@ SetError("FileSystemBackend failed to handle the entry's url."); return false; } - if (file_system_url.type() != storage::kFileSystemTypeNativeLocal) { + if (file_system_url.type() != storage::kFileSystemTypeNativeLocal && + file_system_url.type() != storage::kFileSystemTypeDriveFs) { SetError("Only local directories are supported."); return false; }
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index bb32618..400fba6 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -16,7 +16,6 @@ #include "components/session_manager/core/session_manager.h" #include "components/user_manager/user_manager.h" #include "services/identity/public/cpp/identity_manager.h" -#include "services/identity/public/cpp/identity_test_utils.h" #include "ui/keyboard/public/keyboard_switches.h" namespace file_manager { @@ -979,10 +978,14 @@ account_id, base::UTF8ToUTF16(info.display_name)); Profile* profile = chromeos::ProfileHelper::GetProfileByUserIdHashForTest(info.hash); - identity::IdentityManager* identity_manager = - IdentityManagerFactory::GetForProfile(profile); - if (!identity_manager->HasPrimaryAccount()) - identity::MakePrimaryAccountAvailable(identity_manager, info.email); + // TODO(https://crbug.com/814307): We can't use + // identity::MakePrimaryAccountAvailable from identity_test_utils.h here + // because that DCHECKs that the SigninManager isn't authenticated yet. + // Here, it *can* be already authenticated if a PRE_ test previously set up + // the user. + IdentityManagerFactory::GetForProfile(profile) + ->SetPrimaryAccountSynchronouslyForTests(info.gaia_id, info.email, + "refresh_token"); } GuestMode GetGuestMode() const override { return NOT_IN_GUEST_MODE; }
diff --git a/chrome/browser/chromeos/file_manager/filesystem_api_util.cc b/chrome/browser/chromeos/file_manager/filesystem_api_util.cc index e809636..971c580 100644 --- a/chrome/browser/chromeos/file_manager/filesystem_api_util.cc +++ b/chrome/browser/chromeos/file_manager/filesystem_api_util.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_url_util.h" #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.h" +#include "chrome/browser/chromeos/drive/drive_integration_service.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/fileapi_util.h" @@ -29,6 +30,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" #include "google_apis/drive/task_util.h" +#include "mojo/public/cpp/bindings/callback_helpers.h" #include "storage/browser/fileapi/file_system_context.h" namespace file_manager { @@ -51,6 +53,18 @@ std::move(callback).Run(entry->file_specific_info().content_mime_type()); } +void GetMimeTypeAfterGetMetadata( + base::OnceCallback<void(const base::Optional<std::string>&)> callback, + drive::FileError error, + drivefs::mojom::FileMetadataPtr metadata) { + if (error != drive::FILE_ERROR_OK || !metadata || + metadata->content_mime_type.empty()) { + std::move(callback).Run(base::nullopt); + return; + } + std::move(callback).Run(std::move(metadata->content_mime_type)); +} + // Helper function used to implement GetNonNativeLocalPathMimeType. It extracts // the mime type from the passed metadata from a providing extension. void GetMimeTypeAfterGetMetadataForProvidedFileSystem( @@ -159,27 +173,47 @@ return IsNonNativeFileSystemType(filesystem_url.type()); } +bool HasNonNativeMimeTypeProvider(Profile* profile, + const base::FilePath& path) { + auto* drive_integration_service = + drive::util::GetIntegrationServiceByProfile(profile); + return (drive_integration_service && + drive_integration_service->GetMountPointPath().IsParent(path)) || + IsUnderNonNativeLocalPath(profile, path); +} + void GetNonNativeLocalPathMimeType( Profile* profile, const base::FilePath& path, base::OnceCallback<void(const base::Optional<std::string>&)> callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(IsUnderNonNativeLocalPath(profile, path)); + DCHECK(HasNonNativeMimeTypeProvider(profile, path)); - if (drive::util::IsUnderDriveMountPoint(path)) { - drive::FileSystemInterface* file_system = - drive::util::GetFileSystemByProfile(profile); - if (!file_system) { - base::PostTaskWithTraits( - FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(std::move(callback), base::nullopt)); + auto* drive_integration_service = + drive::util::GetIntegrationServiceByProfile(profile); + base::FilePath drive_relative_path; + if (drive_integration_service && + drive_integration_service->GetRelativeDrivePath(path, + &drive_relative_path)) { + if (drive::FileSystemInterface* file_system = + drive_integration_service->file_system()) { + file_system->GetResourceEntry( + drive::util::ExtractDrivePath(path), + base::BindOnce(&GetMimeTypeAfterGetResourceEntryForDrive, + std::move(callback))); return; } + if (auto* drivefs = drive_integration_service->GetDriveFsInterface()) { + drivefs->GetMetadata( + drive_relative_path, + mojo::WrapCallbackWithDefaultInvokeIfNotRun( + base::BindOnce(&GetMimeTypeAfterGetMetadata, std::move(callback)), + drive::FILE_ERROR_SERVICE_UNAVAILABLE, nullptr)); - file_system->GetResourceEntry( - drive::util::ExtractDrivePath(path), - base::BindOnce(&GetMimeTypeAfterGetResourceEntryForDrive, - std::move(callback))); + return; + } + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), base::nullopt)); return; }
diff --git a/chrome/browser/chromeos/file_manager/filesystem_api_util.h b/chrome/browser/chromeos/file_manager/filesystem_api_util.h index de57e77..b8c1ba9b 100644 --- a/chrome/browser/chromeos/file_manager/filesystem_api_util.h +++ b/chrome/browser/chromeos/file_manager/filesystem_api_util.h
@@ -32,6 +32,10 @@ // requires special handling. bool IsUnderNonNativeLocalPath(Profile* profile, const base::FilePath& path); +// Checks whether |path| points to a filesystem that requires special handling +// for retrieving mime types. +bool HasNonNativeMimeTypeProvider(Profile* profile, const base::FilePath& path); + // Returns the mime type of the file pointed by |path|, and asynchronously sends // the result to |callback|. void GetNonNativeLocalPathMimeType(
diff --git a/chrome/browser/chromeos/login/easy_unlock/chrome_proximity_auth_client.cc b/chrome/browser/chromeos/login/easy_unlock/chrome_proximity_auth_client.cc index 01203d0..2ba8b06 100644 --- a/chrome/browser/chromeos/login/easy_unlock/chrome_proximity_auth_client.cc +++ b/chrome/browser/chromeos/login/easy_unlock/chrome_proximity_auth_client.cc
@@ -19,9 +19,6 @@ #include "chrome/browser/signin/identity_manager_factory.h" #include "chromeos/chromeos_features.h" #include "chromeos/components/multidevice/logging/logging.h" -#include "chromeos/services/device_sync/cryptauth_client_impl.h" -#include "chromeos/services/device_sync/cryptauth_device_manager.h" -#include "chromeos/services/device_sync/cryptauth_enrollment_manager.h" #include "chromeos/services/device_sync/public/cpp/device_sync_client.h" #include "components/prefs/pref_service.h" #include "components/version_info/version_info.h"
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_screenlock_state_handler.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_screenlock_state_handler.cc index 5c631de..b063a24 100644 --- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_screenlock_state_handler.cc +++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_screenlock_state_handler.cc
@@ -130,8 +130,9 @@ // Note that NO_PHONE is not valid in this case because the phone may close // the connection if the auth challenge sent to it is invalid. This case // should be handled as authentication failure. - return (state_ == ScreenlockState::NO_BLUETOOTH || - state_ == ScreenlockState::PHONE_LOCKED); + return state_ == ScreenlockState::INACTIVE || + state_ == ScreenlockState::NO_BLUETOOTH || + state_ == ScreenlockState::PHONE_LOCKED; } void EasyUnlockScreenlockStateHandler::ChangeState(ScreenlockState new_state) {
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service.cc index 4b6eb45..e96e5a12 100644 --- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service.cc +++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service.cc
@@ -39,9 +39,6 @@ #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/power_manager_client.h" #include "chromeos/login/auth/user_context.h" -#include "chromeos/services/device_sync/cryptauth_client_impl.h" -#include "chromeos/services/device_sync/cryptauth_device_manager.h" -#include "chromeos/services/device_sync/cryptauth_enrollment_manager.h" #include "components/account_id/account_id.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_registry_simple.h" @@ -450,10 +447,6 @@ } void EasyUnlockService::HandleAuthFailure(const AccountId& account_id) { - SmartLockMetricsRecorder::RecordAuthResultSignInFailure( - SmartLockMetricsRecorder::SmartLockAuthResultFailureReason:: - kUserControllerSignInFailure); - if (account_id != GetAccountId()) return;
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_regular.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_regular.cc index 396c7d7..9b4e91a9 100644 --- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_regular.cc +++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_regular.cc
@@ -43,9 +43,6 @@ #include "chromeos/components/proximity_auth/screenlock_bridge.h" #include "chromeos/components/proximity_auth/smart_lock_metrics_recorder.h" #include "chromeos/components/proximity_auth/switches.h" -#include "chromeos/services/device_sync/cryptauth_enrollment_manager.h" -#include "chromeos/services/device_sync/cryptauth_gcm_manager_impl.h" -#include "chromeos/services/device_sync/remote_device_loader.h" #include "components/gcm_driver/gcm_profile_service.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h"
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_regular.h b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_regular.h index 8a41f5f..635dbae94 100644 --- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_regular.h +++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_regular.h
@@ -17,8 +17,7 @@ #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_service.h" #include "chromeos/components/multidevice/remote_device_ref.h" #include "chromeos/components/proximity_auth/screenlock_bridge.h" -#include "chromeos/services/device_sync/cryptauth_device_manager.h" -#include "chromeos/services/device_sync/network_request_error.h" +#include "chromeos/services/device_sync/proto/cryptauth_api.pb.h" #include "chromeos/services/device_sync/public/cpp/device_sync_client.h" #include "chromeos/services/multidevice_setup/public/cpp/multidevice_setup_client.h" #include "components/prefs/pref_change_registrar.h" @@ -35,10 +34,6 @@ namespace chromeos { -namespace device_sync { -class RemoteDeviceLoader; -} // namespace device_sync - namespace secure_channel { class SecureChannelClient; } // namespace secure_channel @@ -151,9 +146,6 @@ std::unique_ptr<proximity_auth::ProximityAuthProfilePrefManager> pref_manager_; - // Loads the RemoteDevice instances from CryptAuth and local data. - std::unique_ptr<device_sync::RemoteDeviceLoader> remote_device_loader_; - // If a new RemoteDevice was synced while the screen is locked, we defer // loading the RemoteDevice until the screen is unlocked. For security, // this deferment prevents the lock screen from being changed by a network
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_user_login_flow.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_user_login_flow.cc index fc6acf6..a2b6f7d7 100644 --- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_user_login_flow.cc +++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_user_login_flow.cc
@@ -32,6 +32,9 @@ } bool EasyUnlockUserLoginFlow::HandleLoginFailure(const AuthFailure& failure) { + SmartLockMetricsRecorder::RecordAuthResultSignInFailure( + SmartLockMetricsRecorder::SmartLockAuthResultFailureReason:: + kUserControllerSignInFailure); UMA_HISTOGRAM_ENUMERATION( "SmartLock.AuthResult.SignIn.Failure.UserControllerAuth", failure.reason(), AuthFailure::FailureReason::NUM_FAILURE_REASONS);
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_screen.h b/chrome/browser/chromeos/login/enrollment/enrollment_screen.h index bb17be8b..10121eb 100644 --- a/chrome/browser/chromeos/login/enrollment/enrollment_screen.h +++ b/chrome/browser/chromeos/login/enrollment/enrollment_screen.h
@@ -114,8 +114,6 @@ TestActiveDirectoryEnrollment_ErrorCard); FRIEND_TEST_ALL_PREFIXES(ActiveDirectoryJoinTest, TestActiveDirectoryEnrollment_Streamline); - 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/kiosk_browsertest.cc b/chrome/browser/chromeos/login/kiosk_browsertest.cc index 4caa4cdec..fe1276e 100644 --- a/chrome/browser/chromeos/login/kiosk_browsertest.cc +++ b/chrome/browser/chromeos/login/kiosk_browsertest.cc
@@ -75,7 +75,6 @@ #include "google_apis/gaia/gaia_constants.h" #include "google_apis/gaia/gaia_switches.h" #include "google_apis/gaia/gaia_urls.h" -#include "media/audio/mock_audio_manager.h" #include "media/audio/sounds/audio_stream_handler.h" #include "media/audio/sounds/sounds_manager.h" #include "media/audio/test_audio_thread.h" @@ -84,7 +83,6 @@ #include "services/audio/public/cpp/fake_system_info.h" #include "ui/aura/window.h" #include "ui/base/accelerators/accelerator.h" -#include "ui/base/ui_base_features.h" #include "ui/keyboard/public/keyboard_switches.h" namespace em = enterprise_management; @@ -2357,11 +2355,6 @@ std::move(callback).Run(true); } - // Use class variable for sane lifetime. - // TODO(https://crbug.com/812170): Remove it when media::AudioSystem becomes - // service-based. - std::unique_ptr<media::MockAudioManager> mock_audio_manager_; - private: DISALLOW_COPY_AND_ASSIGN(KioskVirtualKeyboardTest); }; @@ -2369,16 +2362,6 @@ // Verifies that chrome.virtualKeyboard.restrictFeatures and related private // APIs work. IN_PROC_BROWSER_TEST_F(KioskVirtualKeyboardTest, RestrictFeatures) { - // TODO(crbug.com/916221): Crash in media::AudioOutputController::Create(). - if (features::IsSingleProcessMash()) - return; - - // Mock existence of audio input. - // We cannot do this in SetUp because it's overriden in RunTestOnMainThread. - mock_audio_manager_ = std::make_unique<media::MockAudioManager>( - std::make_unique<media::TestAudioThread>()); - mock_audio_manager_->SetHasInputDevices(true); - set_test_app_id(kTestVirtualKeyboardKioskApp); set_test_app_version("0.1"); set_test_crx_file(test_app_id() + ".crx"); @@ -2386,9 +2369,6 @@ extensions::ResultCatcher catcher; StartAppLaunchFromLoginScreen(SimulateNetworkOnlineClosure()); EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); - - // Shutdown should be done in the same thread, thus not in the destructor. - mock_audio_manager_->Shutdown(); } // Specialized test fixture for testing kiosk mode on the
diff --git a/chrome/browser/chromeos/login/screens/base_screen.h b/chrome/browser/chromeos/login/screens/base_screen.h index 58bc9a9..277c224 100644 --- a/chrome/browser/chromeos/login/screens/base_screen.h +++ b/chrome/browser/chromeos/login/screens/base_screen.h
@@ -145,8 +145,6 @@ TestCancel); FRIEND_TEST_ALL_PREFIXES(MultiAuthEnrollmentScreenTest, TestCancel); FRIEND_TEST_ALL_PREFIXES(ProvisionedEnrollmentScreenTest, TestBackButton); - FRIEND_TEST_ALL_PREFIXES(HandsOffWelcomeScreenTest, RequiresNoInput); - FRIEND_TEST_ALL_PREFIXES(HandsOffWelcomeScreenTest, ContinueClickedOnlyOnce); friend class BaseWebUIHandler; friend class NetworkScreenTest;
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc index d2dc1cb..da0a4a9 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.cc +++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -2040,11 +2040,8 @@ } void UserSessionManager::StartAccountManagerMigration(Profile* profile) { - // |migrator| is nullptr for incognito profiles. - auto* migrator = - chromeos::AccountManagerMigratorFactory::GetForBrowserContext(profile); - if (migrator) - migrator->Start(); + chromeos::AccountManagerMigratorFactory::GetForBrowserContext(profile) + ->Start(); } EasyUnlockKeyManager* UserSessionManager::GetEasyUnlockKeyManager() {
diff --git a/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc b/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc index 8cf91a0d..e8f4e539 100644 --- a/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc +++ b/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc
@@ -80,6 +80,12 @@ } void OAuth2LoginManager::RestoreSessionFromSavedTokens() { + // Just return if there is a pending TokenService::LoadCredentials call. + // Session restore continues in OnRefreshTokenAvailable when the call + // finishes. + if (pending_token_service_load_) + return; + ProfileOAuth2TokenService* token_service = GetTokenService(); const std::string primary_account_id = GetPrimaryAccountId(); if (token_service->RefreshTokenIsAvailable(primary_account_id)) { @@ -87,7 +93,7 @@ FireRefreshTokensLoaded(); VerifySessionCookies(); } else { - VLOG(1) << "Waiting for OAuth2 refresh token being loaded from database."; + VLOG(1) << "Loading OAuth2 refresh token from database."; // Flag user with unknown token status in case there are no saved tokens // and OnRefreshTokenAvailable is not called. Flagging it here would @@ -96,6 +102,9 @@ user_manager::UserManager::Get()->SaveUserOAuthStatus( AccountId::FromUserEmail(primary_account_id), user_manager::User::OAUTH_TOKEN_STATUS_UNKNOWN); + + pending_token_service_load_ = true; + token_service->LoadCredentials(primary_account_id); } } @@ -139,6 +148,7 @@ AccountId::FromUserEmail(user_email), user_manager::User::OAUTH2_TOKEN_STATUS_VALID); + pending_token_service_load_ = false; VerifySessionCookies(); } }
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 479d3eee..09863aea 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc +++ b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
@@ -870,6 +870,17 @@ } //////////////////////////////////////////////////////////////////////////////// +// LoginDisplayHostWebUI, views::WidgetObserver: +void LoginDisplayHostWebUI::OnWidgetDestroying(views::Widget* widget) { + DCHECK_EQ(login_window_, widget); + login_window_->RemoveRemovalsObserver(this); + login_window_->RemoveObserver(this); + + login_window_ = nullptr; + login_view_ = nullptr; +} + +//////////////////////////////////////////////////////////////////////////////// // LoginDisplayHostWebUI, MultiUserWindowManagerClient::Observer: void LoginDisplayHostWebUI::OnUserSwitchAnimationFinished() { ShutdownDisplayHost(); @@ -1014,6 +1025,7 @@ views::Widget::ANIMATE_HIDE); } + login_window_->AddObserver(this); login_window_->AddRemovalsObserver(this); login_window_->SetContentsView(login_view_); @@ -1051,6 +1063,7 @@ new CloseAfterCommit(login_window_); } login_window_->RemoveRemovalsObserver(this); + login_window_->RemoveObserver(this); login_window_ = nullptr; }
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_webui.h b/chrome/browser/chromeos/login/ui/login_display_host_webui.h index 1d8b5f8..818c46b 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_webui.h +++ b/chrome/browser/chromeos/login/ui/login_display_host_webui.h
@@ -29,6 +29,7 @@ #include "ui/display/display_observer.h" #include "ui/events/devices/input_device_event_observer.h" #include "ui/gfx/geometry/rect.h" +#include "ui/views/widget/widget_observer.h" #include "ui/views/widget/widget_removals_observer.h" namespace ash { @@ -50,6 +51,7 @@ public display::DisplayObserver, public ui::InputDeviceEventObserver, public views::WidgetRemovalsObserver, + public views::WidgetObserver, public MultiUserWindowManagerClient::Observer { public: LoginDisplayHostWebUI(); @@ -129,6 +131,9 @@ // views::WidgetRemovalsObserver: void OnWillRemoveView(views::Widget* widget, views::View* view) override; + // views::WidgetObserver: + void OnWidgetDestroying(views::Widget* widget) override; + // MultiUserWindowManagerClient::Observer: void OnUserSwitchAnimationFinished() override;
diff --git a/chrome/browser/chromeos/tether/tether_service.cc b/chrome/browser/chromeos/tether/tether_service.cc index 336a89a..60cd0928 100644 --- a/chrome/browser/chromeos/tether/tether_service.cc +++ b/chrome/browser/chromeos/tether/tether_service.cc
@@ -24,7 +24,6 @@ #include "chromeos/network/device_state.h" #include "chromeos/network/network_connect.h" #include "chromeos/network/network_type_pattern.h" -#include "chromeos/services/device_sync/cryptauth_enrollment_manager.h" #include "chromeos/services/multidevice_setup/public/cpp/prefs.h" #include "chromeos/services/secure_channel/public/cpp/client/secure_channel_client.h" #include "components/pref_registry/pref_registry_syncable.h"
diff --git a/chrome/browser/chromeos/tether/tether_service.h b/chrome/browser/chromeos/tether/tether_service.h index fffcf8d..e6c9057 100644 --- a/chrome/browser/chromeos/tether/tether_service.h +++ b/chrome/browser/chromeos/tether/tether_service.h
@@ -16,7 +16,6 @@ #include "chromeos/dbus/power_manager_client.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_state_handler_observer.h" -#include "chromeos/services/device_sync/cryptauth_device_manager.h" #include "chromeos/services/device_sync/public/cpp/device_sync_client.h" #include "chromeos/services/multidevice_setup/public/cpp/multidevice_setup_client.h" #include "components/keyed_service/core/keyed_service.h"
diff --git a/chrome/browser/devtools/device/android_device_manager.cc b/chrome/browser/devtools/device/android_device_manager.cc index 2d6c4ed..8dcb5b60 100644 --- a/chrome/browser/devtools/device/android_device_manager.cc +++ b/chrome/browser/devtools/device/android_device_manager.cc
@@ -540,9 +540,10 @@ if (!thread_) return; // Shut down thread on a thread other than UI so it can join a thread. - base::PostTaskWithTraits(FROM_HERE, - {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, - base::BindOnce(&HandlerThread::StopThread, thread_)); + base::PostTaskWithTraits( + FROM_HERE, + {base::WithBaseSyncPrimitives(), base::TaskPriority::BEST_EFFORT}, + base::BindOnce(&HandlerThread::StopThread, thread_)); } // static
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc index c9cf0a2..d3c6d4b 100644 --- a/chrome/browser/download/download_browsertest.cc +++ b/chrome/browser/download/download_browsertest.cc
@@ -1228,7 +1228,7 @@ CheckDownload(browser(), file, file); } -#if defined(OS_WIN) || defined(OS_LINUX) +#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) // Download a file and confirm that the file is correctly quarantined. // // TODO(asanka): We should enable the test on Mac as well, but currently
diff --git a/chrome/browser/download/notification/download_notification_interactive_uitest.cc b/chrome/browser/download/notification/download_notification_interactive_uitest.cc index bdaa5510..c959179 100644 --- a/chrome/browser/download/notification/download_notification_interactive_uitest.cc +++ b/chrome/browser/download/notification/download_notification_interactive_uitest.cc
@@ -40,7 +40,6 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/url_request/url_request_slow_download_job.h" #include "services/identity/public/cpp/identity_manager.h" -#include "services/identity/public/cpp/identity_test_utils.h" #include "ui/base/l10n/l10n_util.h" #include "url/gurl.h" @@ -878,11 +877,14 @@ base::UTF8ToUTF16(info.display_name)); Profile* profile = chromeos::ProfileHelper::GetProfileByUserIdHashForTest(info.hash); - - identity::IdentityManager* identity_manager = - IdentityManagerFactory::GetForProfile(profile); - if (!identity_manager->HasPrimaryAccount()) - identity::MakePrimaryAccountAvailable(identity_manager, info.email); + // TODO(https://crbug.com/814307): We can't use + // identity::MakePrimaryAccountAvailable from identity_test_utils.h here + // because that DCHECKs that the SigninManager isn't authenticated yet. + // Here, it *can* be already authenticated if a PRE_ test previously set up + // the user. + IdentityManagerFactory::GetForProfile(profile) + ->SetPrimaryAccountSynchronouslyForTests(info.gaia_id, info.email, + "refresh_token"); } std::unique_ptr<NotificationDisplayServiceTester> display_service1_;
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc b/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc index c4229c5..58185ec 100644 --- a/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc +++ b/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/scoped_observer.h" #include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/api/extension_action/test_extension_action_api_observer.h" #include "chrome/browser/extensions/extension_action.h" #include "chrome/browser/extensions/extension_action_manager.h" @@ -20,6 +21,7 @@ #include "content/public/test/test_utils.h" #include "extensions/browser/browsertest_util.h" #include "extensions/browser/state_store.h" +#include "extensions/common/manifest_constants.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/test_extension_dir.h" #include "ui/base/window_open_disposition.h" @@ -57,13 +59,46 @@ DISALLOW_COPY_AND_ASSIGN(TestStateStoreObserver); }; +enum class TestActionType { + kBrowser, + kPage, +}; + } // namespace -using ExtensionActionAPITest = ExtensionApiTest; +class ExtensionActionAPITest : public ExtensionApiTest { + public: + ExtensionActionAPITest() {} + ~ExtensionActionAPITest() override {} + + const char* GetManifestKey(TestActionType action_type) { + switch (action_type) { + case TestActionType::kBrowser: + return manifest_keys::kBrowserAction; + case TestActionType::kPage: + return manifest_keys::kPageAction; + } + NOTREACHED(); + return nullptr; + } + + private: + DISALLOW_COPY_AND_ASSIGN(ExtensionActionAPITest); +}; + +// Alias these for readability, when a test only exercises one type of action. +using BrowserActionAPITest = ExtensionActionAPITest; +using PageActionAPITest = ExtensionActionAPITest; + +// A class that runs tests exercising both page and browser action behavior. +class MultiActionAPITest : public ExtensionActionAPITest, + public testing::WithParamInterface<TestActionType> { +}; // Check that updating the browser action badge for a specific tab id does not // cause a disk write (since we only persist the defaults). -IN_PROC_BROWSER_TEST_F(ExtensionActionAPITest, TestNoUnnecessaryIO) { +// Only browser actions persist settings. +IN_PROC_BROWSER_TEST_F(BrowserActionAPITest, TestNoUnnecessaryIO) { ExtensionTestMessageListener ready_listener("ready", false); TestExtensionDir test_dir; @@ -132,19 +167,22 @@ // Verify that tab-specific values are cleared on navigation and on tab // removal. Regression test for https://crbug.com/834033. -IN_PROC_BROWSER_TEST_F(ExtensionActionAPITest, +IN_PROC_BROWSER_TEST_P(MultiActionAPITest, ValuesAreClearedOnNavigationAndTabRemoval) { ASSERT_TRUE(StartEmbeddedTestServer()); TestExtensionDir test_dir; - test_dir.WriteManifest( + constexpr char kManifestTemplate[] = R"({ "name": "Extension", "description": "An extension", "manifest_version": 2, "version": "0.1", - "browser_action": {} - })"); + "%s": {} + })"; + + test_dir.WriteManifest( + base::StringPrintf(kManifestTemplate, GetManifestKey(GetParam()))); const Extension* extension = LoadExtension(test_dir.UnpackedPath()); ASSERT_TRUE(extension); @@ -185,4 +223,44 @@ EXPECT_FALSE(action->HasTitle(tab_id)); } +// Tests that tooltips of an extension action icon can be specified using UTF8. +// See http://crbug.com/25349. +IN_PROC_BROWSER_TEST_P(MultiActionAPITest, TitleLocalization) { + TestExtensionDir test_dir; + constexpr char kManifestTemplate[] = + R"({ + "name": "Hreggvi\u00F0ur is my name", + "description": "Hreggvi\u00F0ur: l10n action", + "manifest_version": 2, + "version": "0.1", + "%s": { + "default_title": "Hreggvi\u00F0ur" + } + })"; + + test_dir.WriteManifest( + base::StringPrintf(kManifestTemplate, GetManifestKey(GetParam()))); + const Extension* extension = LoadExtension(test_dir.UnpackedPath()); + ASSERT_TRUE(extension); + + auto* action_manager = ExtensionActionManager::Get(profile()); + ExtensionAction* action = action_manager->GetExtensionAction(*extension); + ASSERT_TRUE(action); + + EXPECT_EQ(base::WideToUTF8(L"Hreggvi\u00F0ur: l10n action"), + extension->description()); + EXPECT_EQ(base::WideToUTF8(L"Hreggvi\u00F0ur is my name"), extension->name()); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + int tab_id = SessionTabHelper::IdForTab(web_contents).id(); + EXPECT_EQ(base::WideToUTF8(L"Hreggvi\u00F0ur"), action->GetTitle(tab_id)); + EXPECT_EQ(base::WideToUTF8(L"Hreggvi\u00F0ur"), + action->GetTitle(ExtensionAction::kDefaultTabId)); +} + +INSTANTIATE_TEST_CASE_P(, + MultiActionAPITest, + testing::Values(TestActionType::kBrowser, + TestActionType::kPage)); + } // namespace extensions
diff --git a/chrome/browser/extensions/api/file_handlers/non_native_file_system_delegate_chromeos.cc b/chrome/browser/extensions/api/file_handlers/non_native_file_system_delegate_chromeos.cc index 4ca93379..f4edcbf 100644 --- a/chrome/browser/extensions/api/file_handlers/non_native_file_system_delegate_chromeos.cc +++ b/chrome/browser/extensions/api/file_handlers/non_native_file_system_delegate_chromeos.cc
@@ -24,6 +24,13 @@ Profile::FromBrowserContext(context), path); } +bool NonNativeFileSystemDelegateChromeOS::HasNonNativeMimeTypeProvider( + content::BrowserContext* context, + const base::FilePath& path) { + return file_manager::util::HasNonNativeMimeTypeProvider( + Profile::FromBrowserContext(context), path); +} + void NonNativeFileSystemDelegateChromeOS::GetNonNativeLocalPathMimeType( content::BrowserContext* context, const base::FilePath& path,
diff --git a/chrome/browser/extensions/api/file_handlers/non_native_file_system_delegate_chromeos.h b/chrome/browser/extensions/api/file_handlers/non_native_file_system_delegate_chromeos.h index 575d8d0e..d9405f8 100644 --- a/chrome/browser/extensions/api/file_handlers/non_native_file_system_delegate_chromeos.h +++ b/chrome/browser/extensions/api/file_handlers/non_native_file_system_delegate_chromeos.h
@@ -27,6 +27,8 @@ // extensions::NonNativeFileSystemDelegate: bool IsUnderNonNativeLocalPath(content::BrowserContext* context, const base::FilePath& path) override; + bool HasNonNativeMimeTypeProvider(content::BrowserContext* context, + const base::FilePath& path) override; void GetNonNativeLocalPathMimeType( content::BrowserContext* context, const base::FilePath& path,
diff --git a/chrome/browser/extensions/browser_action_apitest.cc b/chrome/browser/extensions/browser_action_apitest.cc deleted file mode 100644 index fcf84caa..0000000 --- a/chrome/browser/extensions/browser_action_apitest.cc +++ /dev/null
@@ -1,33 +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 <stddef.h> - -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "extensions/browser/extension_registry.h" - -// Tests that tooltips of a browser action icon can be specified using UTF8. -// See http://crbug.com/25349. -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, TitleLocalizationBrowserAction) { - extension::ExtensionRegistry* registry = - extensions::ExtensionRegistry::Get(browser()->profile()); - const size_t size_before = registry->enabled_extensions().size(); - base::FilePath extension_path(test_data_dir_.AppendASCII("browsertest") - .AppendASCII("title_localized")); - const Extension* extension = LoadExtension(extension_path); - ASSERT_TRUE(extension); - - ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); - - EXPECT_STREQ(base::WideToUTF8( - L"Hreggvi\u00F0ur: l10n browser action").c_str(), - extension->description().c_str()); - EXPECT_STREQ(base::WideToUTF8(L"Hreggvi\u00F0ur is my name").c_str(), - extension->name().c_str()); - int tab_id = ExtensionTabUtil::GetTabId( - browser()->tab_strip_model()->GetActiveWebContents()); - EXPECT_STREQ(base::WideToUTF8(L"Hreggvi\u00F0ur").c_str(), - extension->browser_action()->GetTitle(tab_id).c_str()); -}
diff --git a/chrome/browser/extensions/page_action_browsertest.cc b/chrome/browser/extensions/page_action_browsertest.cc index 3319155b..787706e 100644 --- a/chrome/browser/extensions/page_action_browsertest.cc +++ b/chrome/browser/extensions/page_action_browsertest.cc
@@ -24,8 +24,6 @@ const std::string kFeedPage = "/feeds/feed.html"; const std::string kNoFeedPage = "/feeds/no_feed.html"; -const std::string kLocalization = - "/extensions/browsertest/title_localized_pa/simple.html"; const std::string kHashPageA = "/extensions/api_test/page_action/hash_change/test_page_A.html"; @@ -172,38 +170,5 @@ << " ms" << std::flush; } -// Tests that tooltips of a page action icon can be specified using UTF8. -// See http://crbug.com/25349. -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, TitleLocalizationPageAction) { - ASSERT_TRUE(embedded_test_server()->Start()); - - ExtensionRegistry* registry = - extensions::ExtensionRegistry::Get(browser()->profile()); - const size_t size_before = registry->enabled_extensions().size(); - - base::FilePath extension_path(test_data_dir_.AppendASCII("browsertest") - .AppendASCII("title_localized_pa")); - const Extension* extension = LoadExtension(extension_path); - ASSERT_TRUE(extension); - - // Any navigation prompts the location bar to load the page action. - GURL url = embedded_test_server()->GetURL(kLocalization); - ui_test_utils::NavigateToURL(browser(), url); - ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1)); - - ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); - - EXPECT_STREQ(base::WideToUTF8(L"Hreggvi\u00F0ur: l10n page action").c_str(), - extension->description().c_str()); - EXPECT_STREQ(base::WideToUTF8(L"Hreggvi\u00F0ur is my name").c_str(), - extension->name().c_str()); - int tab_id = ExtensionTabUtil::GetTabId( - browser()->tab_strip_model()->GetActiveWebContents()); - EXPECT_STREQ(base::WideToUTF8(L"Hreggvi\u00F0ur").c_str(), - ExtensionActionManager::Get(browser()->profile())-> - GetPageAction(*extension)-> - GetTitle(tab_id).c_str()); -} - } // namespace } // namespace extensions
diff --git a/chrome/browser/media/webrtc/native_desktop_media_list.cc b/chrome/browser/media/webrtc/native_desktop_media_list.cc index 867c10f..7288cfac 100644 --- a/chrome/browser/media/webrtc/native_desktop_media_list.cc +++ b/chrome/browser/media/webrtc/native_desktop_media_list.cc
@@ -251,7 +251,8 @@ } NativeDesktopMediaList::~NativeDesktopMediaList() { - base::ThreadRestrictions::ScopedAllowIO allow_io; + // This thread should mostly be an idle observer. Stopping it should be fast. + base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_thread_join; thread_.task_runner()->DeleteSoon(FROM_HERE, worker_.release()); thread_.Stop(); }
diff --git a/chrome/browser/media/webrtc/webrtc_log_uploader.cc b/chrome/browser/media/webrtc/webrtc_log_uploader.cc index a892aa2..b0ab4876 100644 --- a/chrome/browser/media/webrtc/webrtc_log_uploader.cc +++ b/chrome/browser/media/webrtc/webrtc_log_uploader.cc
@@ -76,6 +76,15 @@ post_data->append("\r\n"); } +// Helper for WebRtcLogUploader::CompressLog(). +void ResizeForNextOutput(std::string* compressed_log, z_stream* stream) { + size_t old_size = compressed_log->size() - stream->avail_out; + compressed_log->resize(old_size + kIntermediateCompressionBufferBytes); + stream->next_out = + reinterpret_cast<unsigned char*>(&(*compressed_log)[old_size]); + stream->avail_out = kIntermediateCompressionBufferBytes; +} + } // namespace WebRtcLogUploadDoneData::WebRtcLogUploadDoneData() {} @@ -87,10 +96,7 @@ WebRtcLogUploader::WebRtcLogUploader() : background_task_runner_(base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT})), - log_count_(0), - post_data_(NULL), - shutting_down_(false) {} + {base::MayBlock(), base::TaskPriority::BEST_EFFORT})) {} WebRtcLogUploader::~WebRtcLogUploader() { DCHECK_CALLED_ON_VALID_THREAD(create_thread_checker_); @@ -120,8 +126,7 @@ DCHECK(meta_data.get()); DCHECK(!upload_done_data.log_path.empty()); - std::string compressed_log; - CompressLog(&compressed_log, log_buffer.get()); + std::string compressed_log = CompressLog(log_buffer.get()); std::string local_log_id; @@ -247,8 +252,7 @@ log_paths.log_path); // Store the native log with a ".gz" extension. - std::string compressed_log; - CompressLog(&compressed_log, log_buffer.get()); + std::string compressed_log = CompressLog(log_buffer.get()); base::FilePath native_log_path = log_paths.log_path.AppendASCII(log_id).AddExtension( FILE_PATH_LITERAL(".gz")); @@ -303,7 +307,7 @@ void WebRtcLogUploader::OnSimpleLoaderComplete( SimpleURLLoaderList::iterator it, - WebRtcLogUploadDoneData upload_done_data, + const WebRtcLogUploadDoneData& upload_done_data, std::unique_ptr<std::string> response_body) { DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK(!shutting_down_); @@ -416,8 +420,7 @@ post_data); } -void WebRtcLogUploader::CompressLog(std::string* compressed_log, - WebRtcLogBuffer* buffer) { +std::string WebRtcLogUploader::CompressLog(WebRtcLogBuffer* buffer) { z_stream stream = {0}; int result = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, // windowBits = 15 is default, 16 is added to @@ -427,15 +430,15 @@ Z_DEFAULT_STRATEGY); DCHECK_EQ(Z_OK, result); - uint8_t intermediate_buffer[kIntermediateCompressionBufferBytes] = {0}; - ResizeForNextOutput(compressed_log, &stream); - uint32_t read = 0; + std::string compressed_log; + ResizeForNextOutput(&compressed_log, &stream); + uint8_t intermediate_buffer[kIntermediateCompressionBufferBytes] = {0}; webrtc_logging::PartialCircularBuffer read_buffer(buffer->Read()); do { if (stream.avail_in == 0) { - read = read_buffer.Read(&intermediate_buffer[0], - sizeof(intermediate_buffer)); + uint32_t read = read_buffer.Read(&intermediate_buffer[0], + sizeof(intermediate_buffer)); stream.next_in = &intermediate_buffer[0]; stream.avail_in = read; if (read != kIntermediateCompressionBufferBytes) @@ -444,29 +447,21 @@ result = deflate(&stream, Z_SYNC_FLUSH); DCHECK_EQ(Z_OK, result); if (stream.avail_out == 0) - ResizeForNextOutput(compressed_log, &stream); + ResizeForNextOutput(&compressed_log, &stream); } while (true); // Ensure we have enough room in the output buffer. Easier to always just do a // resize than looping around and resize if needed. if (stream.avail_out < kIntermediateCompressionBufferBytes) - ResizeForNextOutput(compressed_log, &stream); + ResizeForNextOutput(&compressed_log, &stream); result = deflate(&stream, Z_FINISH); DCHECK_EQ(Z_STREAM_END, result); result = deflateEnd(&stream); DCHECK_EQ(Z_OK, result); - compressed_log->resize(compressed_log->size() - stream.avail_out); -} - -void WebRtcLogUploader::ResizeForNextOutput(std::string* compressed_log, - z_stream* stream) { - size_t old_size = compressed_log->size() - stream->avail_out; - compressed_log->resize(old_size + kIntermediateCompressionBufferBytes); - stream->next_out = - reinterpret_cast<unsigned char*>(&(*compressed_log)[old_size]); - stream->avail_out = kIntermediateCompressionBufferBytes; + compressed_log.resize(compressed_log.size() - stream.avail_out); + return compressed_log; } void WebRtcLogUploader::UploadCompressedLog(
diff --git a/chrome/browser/media/webrtc/webrtc_log_uploader.h b/chrome/browser/media/webrtc/webrtc_log_uploader.h index d5bbcd7..840a2b53 100644 --- a/chrome/browser/media/webrtc/webrtc_log_uploader.h +++ b/chrome/browser/media/webrtc/webrtc_log_uploader.h
@@ -8,6 +8,7 @@ #include <stdint.h> #include <list> +#include <map> #include <memory> #include <string> @@ -119,9 +120,7 @@ const base::FilePath& outgoing_rtp_dump, const std::map<std::string, std::string>& meta_data); - void CompressLog(std::string* compressed_log, WebRtcLogBuffer* buffer); - - void ResizeForNextOutput(std::string* compressed_log, z_stream* stream); + std::string CompressLog(WebRtcLogBuffer* buffer); void UploadCompressedLog(const WebRtcLogUploadDoneData& upload_done_data, std::unique_ptr<std::string> post_data); @@ -171,7 +170,7 @@ std::list<std::unique_ptr<network::SimpleURLLoader>>; void OnSimpleLoaderComplete(SimpleURLLoaderList::iterator it, - WebRtcLogUploadDoneData upload_done_data, + const WebRtcLogUploadDoneData& upload_done_data, std::unique_ptr<std::string> response_body); // This is the UI thread for Chromium. Some other thread for tests. @@ -183,17 +182,17 @@ // Keeps track of number of currently open logs. Must be accessed on the IO // thread. - int log_count_; + int log_count_ = 0; // For testing purposes, see OverrideUploadWithBufferForTesting. Only accessed // on the FILE thread. - std::string* post_data_; + std::string* post_data_ = nullptr; // Only accessed on the IO thread. SimpleURLLoaderList pending_uploads_; // When shutting down, don't create new URL loaders. - bool shutting_down_; + bool shutting_down_ = false; // URLLoaderFactory bound to the IO thread. network::mojom::URLLoaderFactoryPtr url_loader_factory_;
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc index 590fc97..6bfa3bc 100644 --- a/chrome/browser/metrics/chrome_metrics_service_client.cc +++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -65,6 +65,7 @@ #include "components/history/core/browser/history_service.h" #include "components/metrics/call_stack_profile_metrics_provider.h" #include "components/metrics/component_metrics_provider.h" +#include "components/metrics/cpu_metrics_provider.h" #include "components/metrics/drive_metrics_provider.h" #include "components/metrics/field_trials_provider.h" #include "components/metrics/gpu/gpu_metrics_provider.h" @@ -626,6 +627,9 @@ std::make_unique<metrics::GPUMetricsProvider>()); metrics_service_->RegisterMetricsProvider( + std::make_unique<metrics::CPUMetricsProvider>()); + + metrics_service_->RegisterMetricsProvider( std::make_unique<metrics::ScreenInfoMetricsProvider>()); metrics_service_->RegisterMetricsProvider(CreateFileMetricsProvider( @@ -744,6 +748,15 @@ std::make_unique<ChromeOSMetricsProvider>()); #endif // !defined(OS_CHROMEOS) + metrics_service_->RegisterMetricsProvider( + std::make_unique<metrics::GPUMetricsProvider>()); + + metrics_service_->RegisterMetricsProvider( + std::make_unique<metrics::CPUMetricsProvider>()); + + metrics_service_->RegisterMetricsProvider( + std::make_unique<metrics::ScreenInfoMetricsProvider>()); + // TODO(rkaplow): Support synthetic trials for UKM. ukm_service_->RegisterMetricsProvider( std::make_unique<variations::FieldTrialsProvider>(nullptr,
diff --git a/chrome/browser/metrics/thread_watcher.cc b/chrome/browser/metrics/thread_watcher.cc index 5a28d60..e30b515f 100644 --- a/chrome/browser/metrics/thread_watcher.cc +++ b/chrome/browser/metrics/thread_watcher.cc
@@ -867,7 +867,7 @@ if (startup_watchdog->IsJoinable()) { // Allow the watchdog thread to shutdown on UI. Watchdog thread shutdowns // very fast. - base::ThreadRestrictions::ScopedAllowIO allow_io; + base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_thread_join; delete startup_watchdog; return; }
diff --git a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base.cc b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base.cc index c4cf3cd..91e8ee0b 100644 --- a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base.cc +++ b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base.cc
@@ -229,6 +229,7 @@ base::Optional<base::TimeDelta> parse_blocked_on_script_load_duration; base::Optional<base::TimeDelta> parse_stop; base::Optional<base::TimeDelta> page_end_time; + base::Optional<base::TimeDelta> main_frame_fetch_start; if (WasStartedInForegroundOptionalEventInForeground(timing.response_start, info)) { response_start = timing.response_start; @@ -263,6 +264,10 @@ timing.parse_timing->parse_stop, info)) { parse_stop = timing.parse_timing->parse_stop; } + if (navigation_start_ && main_frame_fetch_start_) { + main_frame_fetch_start = + main_frame_fetch_start_.value() - navigation_start_.value(); + } if (info.started_in_foreground && info.page_end_time.has_value()) { // This should be reported even when the app goes into the background which // is excluded in |WasStartedInForegroundOptionalEventInForeground|. @@ -312,9 +317,9 @@ experimental_first_meaningful_paint, first_input_delay, parse_blocked_on_script_load_duration, parse_stop, page_end_time, lite_page_redirect_penalty_, lite_page_redirect_status_, - navigation_start_to_main_frame_fetch_start_, network_bytes, - original_network_bytes, total_page_size_bytes, cached_fraction, - app_background_occurred, opted_out_, renderer_memory_usage_kb_, host_id, + main_frame_fetch_start, network_bytes, original_network_bytes, + total_page_size_bytes, cached_fraction, app_background_occurred, + opted_out_, renderer_memory_usage_kb_, host_id, ConvertPLMPageEndReasonToProto(info.page_end_reason), touch_count_, scroll_count_, redirect_count_); GetPingbackClient()->SendPingback(*data_, data_reduction_proxy_timing); @@ -343,9 +348,8 @@ if (extra_request_complete_info.resource_type == content::RESOURCE_TYPE_MAIN_FRAME) { - navigation_start_to_main_frame_fetch_start_ = - extra_request_complete_info.load_timing_info->request_start - - navigation_start_; + main_frame_fetch_start_ = + extra_request_complete_info.load_timing_info->request_start; } }
diff --git a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base.h b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base.h index c1c5f52..367e2f6 100644 --- a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base.h +++ b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_base.h
@@ -185,11 +185,10 @@ // The time when the navigation started. Used to estimate // |navigation_start_to_main_frame_fetch_start_|. - base::TimeTicks navigation_start_; + base::Optional<base::TimeTicks> navigation_start_; - // The duration between the navigation start as reported by the navigation - // handle, and when the fetchStart of the main page HTML. - base::TimeDelta navigation_start_to_main_frame_fetch_start_; + // The time of the fetchStart of the main page HTML. + base::Optional<base::TimeTicks> main_frame_fetch_start_; // The penalty of navigating to a lite page redirect preview. base::Optional<base::TimeDelta> lite_page_redirect_penalty_;
diff --git a/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc b/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc index 5da1475..ac33825 100644 --- a/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc +++ b/chrome/browser/page_load_metrics/observers/use_counter/ukm_features.cc
@@ -23,7 +23,10 @@ const UseCounterPageLoadMetricsObserver::UkmFeatureList& UseCounterPageLoadMetricsObserver::GetAllowedUkmFeatures() { static base::NoDestructor<UseCounterPageLoadMetricsObserver::UkmFeatureList> - opt_in_features({ + // We explicitly use an std::initializer_list below to work around GCC + // bug 84849, which causes having a base::NoDestructor<T<U>> and passing + // an initializer list of Us does not work. + opt_in_features(std::initializer_list<WebFeature>({ WebFeature::kNavigatorVibrate, WebFeature::kNavigatorVibrateSubFrame, WebFeature::kTouchEventPreventedNoTouchAction, @@ -93,6 +96,6 @@ WebFeature::kDownloadInAdFrameWithUserGesture, WebFeature::kDownloadInAdFrameWithoutUserGesture, WebFeature::kOpenWebDatabase, - }); + })); return *opt_in_features; }
diff --git a/chrome/browser/printing/printer_query.cc b/chrome/browser/printing/printer_query.cc index cc23687..09f8e164 100644 --- a/chrome/browser/printing/printer_query.cc +++ b/chrome/browser/printing/printer_query.cc
@@ -136,7 +136,7 @@ // http://crbug.com/66082: We're blocking on the PrinterQuery's worker // thread. It's not clear to me if this may result in blocking the current // thread for an unacceptable time. We should probably fix it. - base::ThreadRestrictions::ScopedAllowIO allow_io; + base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_thread_join; worker_->Stop(); worker_.reset(); }
diff --git a/chrome/browser/renderer_context_menu/context_menu_content_type_factory.cc b/chrome/browser/renderer_context_menu/context_menu_content_type_factory.cc index 07e89d3..a65df920 100644 --- a/chrome/browser/renderer_context_menu/context_menu_content_type_factory.cc +++ b/chrome/browser/renderer_context_menu/context_menu_content_type_factory.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/renderer_context_menu/context_menu_content_type_factory.h" +#include <memory> + #include "base/bind.h" #include "chrome/common/url_constants.h" #include "components/renderer_context_menu/context_menu_content_type.h" @@ -66,44 +68,54 @@ } // static. -ContextMenuContentType* ContextMenuContentTypeFactory::Create( +std::unique_ptr<ContextMenuContentType> ContextMenuContentTypeFactory::Create( content::WebContents* web_contents, const content::ContextMenuParams& params) { if (IsUserSessionBlocked()) - return new NullContextMenuContentType(web_contents, params); + return std::make_unique<NullContextMenuContentType>(web_contents, params); - return SetInternalResourcesURLChecker(CreateInternal(web_contents, params)); -} - -// static. -ContextMenuContentType* -ContextMenuContentTypeFactory::SetInternalResourcesURLChecker( - ContextMenuContentType* content_type) { - content_type->set_internal_resources_url_checker( - base::Bind(&CheckInternalResourcesURL)); + std::unique_ptr<ContextMenuContentType> content_type = + CreateInternal(web_contents, params); + SetInternalResourcesURLChecker(content_type.get()); return content_type; } +// static. +void ContextMenuContentTypeFactory::SetInternalResourcesURLChecker( + ContextMenuContentType* content_type) { + content_type->set_internal_resources_url_checker( + base::Bind(&CheckInternalResourcesURL)); +} + // static -ContextMenuContentType* ContextMenuContentTypeFactory::CreateInternal( +std::unique_ptr<ContextMenuContentType> +ContextMenuContentTypeFactory::CreateInternal( content::WebContents* web_contents, const content::ContextMenuParams& params) { #if BUILDFLAG(ENABLE_EXTENSIONS) - if (chrome::IsRunningInForcedAppMode()) - return new ContextMenuContentTypeAppMode(web_contents, params); + if (chrome::IsRunningInForcedAppMode()) { + return base::WrapUnique( + new ContextMenuContentTypeAppMode(web_contents, params)); + } - if (extensions::WebViewGuest::FromWebContents(web_contents)) - return new ContextMenuContentTypeWebView(web_contents, params); + if (extensions::WebViewGuest::FromWebContents(web_contents)) { + return base::WrapUnique( + new ContextMenuContentTypeWebView(web_contents, params)); + } const extensions::ViewType view_type = extensions::GetViewType(web_contents); - if (view_type == extensions::VIEW_TYPE_APP_WINDOW) - return new ContextMenuContentTypePlatformApp(web_contents, params); + if (view_type == extensions::VIEW_TYPE_APP_WINDOW) { + return base::WrapUnique( + new ContextMenuContentTypePlatformApp(web_contents, params)); + } - if (view_type == extensions::VIEW_TYPE_EXTENSION_POPUP) - return new ContextMenuContentTypeExtensionPopup(web_contents, params); + if (view_type == extensions::VIEW_TYPE_EXTENSION_POPUP) { + return base::WrapUnique( + new ContextMenuContentTypeExtensionPopup(web_contents, params)); + } #endif - return new ContextMenuContentType(web_contents, params, true); + return std::make_unique<ContextMenuContentType>(web_contents, params, true); }
diff --git a/chrome/browser/renderer_context_menu/context_menu_content_type_factory.h b/chrome/browser/renderer_context_menu/context_menu_content_type_factory.h index 990c03aa..e2cd9248 100644 --- a/chrome/browser/renderer_context_menu/context_menu_content_type_factory.h +++ b/chrome/browser/renderer_context_menu/context_menu_content_type_factory.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_RENDERER_CONTEXT_MENU_CONTEXT_MENU_CONTENT_TYPE_FACTORY_H_ #define CHROME_BROWSER_RENDERER_CONTEXT_MENU_CONTEXT_MENU_CONTENT_TYPE_FACTORY_H_ +#include <memory> + #include "base/macros.h" #include "content/public/common/context_menu_params.h" @@ -16,20 +18,20 @@ class ContextMenuContentTypeFactory { public: - static ContextMenuContentType* Create( + static std::unique_ptr<ContextMenuContentType> Create( content::WebContents* web_contents, const content::ContextMenuParams& params); // Sets the chrome specific url checker for internal resources. // This is exposed for tests. - static ContextMenuContentType* SetInternalResourcesURLChecker( + static void SetInternalResourcesURLChecker( ContextMenuContentType* content_type); private: ContextMenuContentTypeFactory(); virtual ~ContextMenuContentTypeFactory(); - static ContextMenuContentType* CreateInternal( + static std::unique_ptr<ContextMenuContentType> CreateInternal( content::WebContents* web_contents, const content::ContextMenuParams& params);
diff --git a/chrome/browser/renderer_context_menu/context_menu_content_type_unittest.cc b/chrome/browser/renderer_context_menu/context_menu_content_type_unittest.cc index 2f854ae..acf283b 100644 --- a/chrome/browser/renderer_context_menu/context_menu_content_type_unittest.cc +++ b/chrome/browser/renderer_context_menu/context_menu_content_type_unittest.cc
@@ -16,11 +16,14 @@ class ContextMenuContentTypeTest : public ChromeRenderViewHostTestHarness { public: - static ContextMenuContentType* Create( + static std::unique_ptr<ContextMenuContentType> Create( content::WebContents* web_contents, - content::ContextMenuParams& params) { - return ContextMenuContentTypeFactory::SetInternalResourcesURLChecker( - new ContextMenuContentType(web_contents, params, true)); + const content::ContextMenuParams& params) { + auto content_type = + std::make_unique<ContextMenuContentType>(web_contents, params, true); + ContextMenuContentTypeFactory::SetInternalResourcesURLChecker( + content_type.get()); + return content_type; } };
diff --git a/chrome/browser/resources/app_management/BUILD.gn b/chrome/browser/resources/app_management/BUILD.gn index c67292d..19b5cdd 100644 --- a/chrome/browser/resources/app_management/BUILD.gn +++ b/chrome/browser/resources/app_management/BUILD.gn
@@ -17,6 +17,7 @@ ":main_view", ":pwa_permission_view", ":reducers", + ":router", ":store", ":store_client", ":types", @@ -46,6 +47,7 @@ ":browser_proxy", ":main_view", ":pwa_permission_view", + ":router", ":util", ] } @@ -70,6 +72,8 @@ js_library("item") { deps = [ + ":actions", + ":store_client", "//ui/webui/resources/js:load_time_data", ] } @@ -97,6 +101,14 @@ ] } + js_library("router") { + deps = [ + ":actions", + ":constants", + ":store_client", + ] + } + js_library("store") { deps = [ ":reducers",
diff --git a/chrome/browser/resources/app_management/actions.js b/chrome/browser/resources/app_management/actions.js index 323307a..c0f3056 100644 --- a/chrome/browser/resources/app_management/actions.js +++ b/chrome/browser/resources/app_management/actions.js
@@ -9,7 +9,7 @@ cr.define('app_management.actions', function() { /** - * @param {Array<appManagement.mojom.App>} apps + * @param {Array<App>} apps */ function addApps(apps) { return { @@ -19,7 +19,7 @@ } /** - * @param {appManagement.mojom.App} update + * @param {App} update */ function changeApp(update) { return { @@ -38,9 +38,27 @@ }; } + /** + * @param {PageType} pageType + * @param {string=} id + */ + function changePage(pageType, id) { + if (pageType == PageType.DETAIL && !id) { + console.warn( + 'Tried to load app detail page without providing an app id.'); + } + + return { + name: 'change-page', + pageType: pageType, + id: id, + }; + } + return { addApps: addApps, changeApp: changeApp, removeApp: removeApp, + changePage: changePage, }; });
diff --git a/chrome/browser/resources/app_management/api_listener.js b/chrome/browser/resources/app_management/api_listener.js index 5facd053..b7b3b46f 100644 --- a/chrome/browser/resources/app_management/api_listener.js +++ b/chrome/browser/resources/app_management/api_listener.js
@@ -4,22 +4,40 @@ cr.define('app_management.ApiListener', function() { let initialized = false; + let initialListenerId; + function init() { assert(!initialized); - app_management.BrowserProxy.getInstance().handler.getApps(); + const callbackRouter = app_management.BrowserProxy.getInstance().callbackRouter; - app_management.Store.getInstance().init( - app_management.util.createEmptyState()); + initialListenerId = + callbackRouter.onAppsAdded.addListener(initialOnAppsAdded); - callbackRouter.onAppsAdded.addListener(onAppsAdded.bind(this)); - callbackRouter.onAppChanged.addListener(onAppChanged.bind(this)); - callbackRouter.onAppRemoved.addListener(onAppRemoved.bind(this)); + app_management.BrowserProxy.getInstance().handler.getApps(); + initialized = true; } /** + * @param {!Array<App>} apps + */ + function initialOnAppsAdded(apps) { + const initialState = app_management.util.createInitialState(apps); + app_management.Store.getInstance().init(initialState); + + const callbackRouter = + app_management.BrowserProxy.getInstance().callbackRouter; + + callbackRouter.onAppsAdded.addListener(onAppsAdded); + callbackRouter.onAppChanged.addListener(onAppChanged); + callbackRouter.onAppRemoved.addListener(onAppRemoved); + + callbackRouter.removeListener(initialListenerId); + } + + /** * @param {cr.ui.Action} action */ function dispatch(action) { @@ -27,14 +45,14 @@ } /** - * @param {Array<appManagement.mojom.App>} apps + * @param {Array<App>} apps */ function onAppsAdded(apps) { dispatch(app_management.actions.addApps(apps)); } /** - * @param {appManagement.mojom.App} app + * @param {App} app */ function onAppChanged(app) { dispatch(app_management.actions.changeApp(app));
diff --git a/chrome/browser/resources/app_management/app.html b/chrome/browser/resources/app_management/app.html index 0de08c2..b94366ff 100644 --- a/chrome/browser/resources/app_management/app.html +++ b/chrome/browser/resources/app_management/app.html
@@ -1,11 +1,12 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://apps/actions.html"> -<link rel="import" href="chrome://apps/browser_proxy.html"> -<link rel="import" href="chrome://apps/constants.html"> -<link rel="import" href="chrome://apps/main_view.html"> -<link rel="import" href="chrome://apps/pwa_permission_view.html"> -<link rel="import" href="chrome://apps/store.html"> +<link rel="import" href="actions.html"> +<link rel="import" href="browser_proxy.html"> +<link rel="import" href="constants.html"> +<link rel="import" href="main_view.html"> +<link rel="import" href="pwa_permission_view.html"> +<link rel="import" href="router.html"> +<link rel="import" href="store.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toolbar/cr_toolbar.html"> <link rel="import" href="chrome://apps/api_listener.html"> @@ -25,6 +26,7 @@ </cr-toolbar> <app-management-main-view></app-management-main-view> <app-management-pwa-permission-view></app-management-pwa-permission-view> + <app-management-router></app-management-router> </template> <script src="chrome://apps/app.js"></script> </dom-module>
diff --git a/chrome/browser/resources/app_management/constants.js b/chrome/browser/resources/app_management/constants.js index 6522195..2a7089a 100644 --- a/chrome/browser/resources/app_management/constants.js +++ b/chrome/browser/resources/app_management/constants.js
@@ -4,3 +4,13 @@ /** @const {number} */ const NUMBER_OF_APPS_DISPLAYED_DEFAULT = 4; + +/** + * Enumeration of the different subpage types within the app management page. + * @enum {number} + * @const + */ +const PageType = { + MAIN: 0, + DETAIL: 1, +};
diff --git a/chrome/browser/resources/app_management/index.html b/chrome/browser/resources/app_management/index.html index a2773ba..0f446d04 100644 --- a/chrome/browser/resources/app_management/index.html +++ b/chrome/browser/resources/app_management/index.html
@@ -22,7 +22,7 @@ <body> <app-management-app></app-management-app> <script src="chrome://resources/js/load_time_data.js"></script> - <script src="chrome://apps/strings.js"></script> - <link rel="import" href="chrome://apps/app.html"> + <script src="strings.js"></script> + <link rel="import" href="app.html"> </body> </html>
diff --git a/chrome/browser/resources/app_management/item.html b/chrome/browser/resources/app_management/item.html index d112f06d..8bb42d9d6 100644 --- a/chrome/browser/resources/app_management/item.html +++ b/chrome/browser/resources/app_management/item.html
@@ -1,7 +1,9 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://apps/shared_style.html"> -<link rel="import" href="chrome://apps/shared_vars.html"> +<link rel="import" href="actions.html"> +<link rel="import" href="shared_style.html"> +<link rel="import" href="shared_vars.html"> +<link rel="import" href="store_client.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html">
diff --git a/chrome/browser/resources/app_management/item.js b/chrome/browser/resources/app_management/item.js index 5b12945..54841b8 100644 --- a/chrome/browser/resources/app_management/item.js +++ b/chrome/browser/resources/app_management/item.js
@@ -4,6 +4,10 @@ Polymer({ is: 'app-management-item', + behaviors: [ + app_management.StoreClient, + ], + properties: { /** @type {appManagement.mojom.App} */ app: { @@ -11,6 +15,18 @@ }, }, + listeners: { + 'click': 'onClick_', + }, + + /** + * @private + */ + onClick_: function() { + this.dispatch( + app_management.actions.changePage(PageType.DETAIL, this.app.id)); + }, + /** * @param {appManagement.mojom.App} app * @return {string} @@ -19,5 +35,4 @@ iconUrlFromId_: function(app) { return `chrome://extension-icon/${app.id}/128/1`; }, - });
diff --git a/chrome/browser/resources/app_management/main_view.html b/chrome/browser/resources/app_management/main_view.html index 8e69768..beca642c 100644 --- a/chrome/browser/resources/app_management/main_view.html +++ b/chrome/browser/resources/app_management/main_view.html
@@ -1,9 +1,9 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://apps/item.html"> -<link rel="import" href="chrome://apps/shared_style.html"> -<link rel="import" href="chrome://apps/shared_vars.html"> -<link rel="import" href="chrome://apps/store_client.html"> +<link rel="import" href="item.html"> +<link rel="import" href="shared_style.html"> +<link rel="import" href="shared_vars.html"> +<link rel="import" href="store_client.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toolbar/cr_toolbar.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/icon.html">
diff --git a/chrome/browser/resources/app_management/pwa_permission_view.html b/chrome/browser/resources/app_management/pwa_permission_view.html index c4c68c4..473af257 100644 --- a/chrome/browser/resources/app_management/pwa_permission_view.html +++ b/chrome/browser/resources/app_management/pwa_permission_view.html
@@ -1,8 +1,8 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://apps/browser_proxy.html"> -<link rel="import" href="chrome://apps/shared_style.html"> -<link rel="import" href="chrome://apps/shared_vars.html"> +<link rel="import" href="browser_proxy.html"> +<link rel="import" href="shared_style.html"> +<link rel="import" href="shared_vars.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> <link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html">
diff --git a/chrome/browser/resources/app_management/reducers.js b/chrome/browser/resources/app_management/reducers.js index f7e2279..cdcc82c 100644 --- a/chrome/browser/resources/app_management/reducers.js +++ b/chrome/browser/resources/app_management/reducers.js
@@ -68,6 +68,42 @@ } }; + const CurrentPageState = {}; + + /** + * @param {AppMap} apps + * @param {Object} action + * @return {Page} + */ + CurrentPageState.changePage = function(apps, action) { + if (action.pageType == PageType.DETAIL && apps[action.id]) { + return { + pageType: PageType.DETAIL, + selectedAppId: action.id, + }; + } else { + return { + pageType: PageType.MAIN, + selectedAppId: null, + }; + } + }; + + /** + * @param {AppMap} apps + * @param {Page} currentPage + * @param {Object} action + * @return {Page} + */ + CurrentPageState.updateCurrentPage = function(apps, currentPage, action) { + switch (action.name) { + case 'change-page': + return CurrentPageState.changePage(apps, action); + default: + return currentPage; + } + }; + /** * Root reducer for the App Management page. This is called by the store in * response to an action, and the return value is used to update the UI. @@ -78,11 +114,14 @@ function reduceAction(state, action) { return { apps: AppState.updateApps(state.apps, action), + currentPage: CurrentPageState.updateCurrentPage( + state.apps, state.currentPage, action), }; } return { reduceAction: reduceAction, AppState: AppState, + CurrentPageState: CurrentPageState, }; });
diff --git a/chrome/browser/resources/app_management/router.html b/chrome/browser/resources/app_management/router.html new file mode 100644 index 0000000..d8358a0 --- /dev/null +++ b/chrome/browser/resources/app_management/router.html
@@ -0,0 +1,16 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="actions.html"> +<link rel="import" href="store_client.html"> +<link rel="import" href="constants.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-location/iron-location.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-location/iron-query-params.html"> + +<dom-module id="app-management-router"> + <template> + <iron-location query="{{urlQuery_}}" path="{{path_}}"></iron-location> + <iron-query-params params-string="{{query_}}" + params-object="{{queryParams_}}"></iron-query-params> + </template> + <script src="chrome://apps/router.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/app_management/router.js b/chrome/browser/resources/app_management/router.js new file mode 100644 index 0000000..ceb46b0 --- /dev/null +++ b/chrome/browser/resources/app_management/router.js
@@ -0,0 +1,125 @@ +// 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. + +Polymer({ + is: 'app-management-router', + + behaviors: [ + app_management.StoreClient, + ], + + properties: { + /** @private {string} */ + path_: String, + + /** @private {Object} */ + queryParams_: Object, + + /** @private {string} */ + query_: { + type: String, + observer: 'onQueryChanged_', + }, + + /** @private {string} */ + urlQuery_: { + type: String, + observer: 'onUrlQueryChanged_', + }, + + /** @private {PageType} */ + currentPageType_: { + type: Number, + }, + + /** @private {?string} */ + selectedAppId_: { + type: String, + }, + }, + + observers: [ + 'onUrlChanged_(path_, queryParams_)', + 'onStateChanged_(currentPageType_, selectedAppId_)', + ], + + attached: function() { + this.watch('currentPageType_', function(state) { + return state.currentPage.pageType; + }); + this.watch('selectedAppId_', function(state) { + return state.currentPage.selectedAppId; + }); + this.updateFromStore(); + }, + + /** + * @param {?string} current Current value of the query. + * @param {?string} previous Previous value of the query. + * @private + */ + onQueryChanged_: function(current, previous) { + if (previous !== undefined) + this.urlQuery_ = this.query_; + }, + + /** @private */ + onUrlQueryChanged_: function() { + this.query_ = this.urlQuery_; + }, + + /** @private */ + onStateChanged_: function() { + this.debounce('publishUrl', this.publishUrl_); + }, + + /** @private */ + publishUrl_: function() { + this.publishQueryParams_(); + this.publishPath_(); + }, + + /** @private */ + publishQueryParams_: function() { + const newId = this.selectedAppId_; + + this.queryParams_.id = newId; + if (!newId) + delete this.queryParams_.id; + + this.queryParams_ = Object.assign({}, this.queryParams_); + }, + + /** @private */ + publishPath_: function() { + let path = ''; + + if (this.currentPageType_ == PageType.DETAIL) + path = 'detail'; + + this.path_ = '/' + path; + }, + + /** @private */ + onUrlChanged_: function() { + this.debounce('parseUrl', this.parseUrl_); + }, + + /** @private */ + parseUrl_: function() { + const newId = this.queryParams_.id; + + const pageFromUrl = this.path_.substr(1).split('/')[0]; + let newPage = PageType.MAIN; + if (pageFromUrl == 'detail') + newPage = PageType.DETAIL; + else + newPage = PageType.MAIN; + + if (newPage == PageType.DETAIL) + this.dispatch(app_management.actions.changePage(PageType.DETAIL, newId)); + else + this.dispatch(app_management.actions.changePage(newPage)); + }, +});
diff --git a/chrome/browser/resources/app_management/store.html b/chrome/browser/resources/app_management/store.html index 3d997af..3fb5eb0f 100644 --- a/chrome/browser/resources/app_management/store.html +++ b/chrome/browser/resources/app_management/store.html
@@ -1,6 +1,6 @@ <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/cr/ui/store.html"> -<link rel="import" href="chrome://apps/reducers.html"> -<link rel="import" href="chrome://apps/util.html"> +<link rel="import" href="reducers.html"> +<link rel="import" href="util.html"> <script src="chrome://apps/store.js"></script>
diff --git a/chrome/browser/resources/app_management/store_client.html b/chrome/browser/resources/app_management/store_client.html index c35c41a..d61dfe4 100644 --- a/chrome/browser/resources/app_management/store_client.html +++ b/chrome/browser/resources/app_management/store_client.html
@@ -1,5 +1,5 @@ <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/cr/ui/store_client.html"> -<link rel="import" href="chrome://apps/store.html"> +<link rel="import" href="store.html"> <script src="chrome://apps/store_client.js"></script>
diff --git a/chrome/browser/resources/app_management/types.js b/chrome/browser/resources/app_management/types.js index 8ca0613..942fab6 100644 --- a/chrome/browser/resources/app_management/types.js +++ b/chrome/browser/resources/app_management/types.js
@@ -7,6 +7,11 @@ */ /** + * @typedef {appManagement.mojom.App} + */ +let App; + +/** * Maps app ids to Apps. * @typedef {!Object<string, appManagement.mojom.App>} */ @@ -14,7 +19,16 @@ /** * @typedef {{ + * pageType: PageType, + * selectedAppId: ?string, + * }} + */ +let Page; + +/** + * @typedef {{ * apps: AppMap, + * currentPage: Page, * }} */ let AppManagementPageState;
diff --git a/chrome/browser/resources/app_management/util.js b/chrome/browser/resources/app_management/util.js index b3cf51b..76cb9beb 100644 --- a/chrome/browser/resources/app_management/util.js +++ b/chrome/browser/resources/app_management/util.js
@@ -7,12 +7,35 @@ */ cr.define('app_management.util', function() { - /** @return {!AppManagementPageState} */ + /** + * @return {!AppManagementPageState} + */ function createEmptyState() { - return {apps: {}}; + return { + apps: {}, + currentPage: { + pageType: PageType.MAIN, + selectedAppId: null, + } + }; + } + + /** + * @param {!Array<App>} apps + * @return {!AppManagementPageState} + */ + function createInitialState(apps) { + const initialState = createEmptyState(); + + for (const app of apps) { + initialState.apps[app.id] = app; + } + + return initialState; } return { createEmptyState: createEmptyState, + createInitialState: createInitialState, }; });
diff --git a/chrome/browser/resources/bluetooth_internals/adapter_broker.js b/chrome/browser/resources/bluetooth_internals/adapter_broker.js index d345167a..6ffe0eb 100644 --- a/chrome/browser/resources/bluetooth_internals/adapter_broker.js +++ b/chrome/browser/resources/bluetooth_internals/adapter_broker.js
@@ -31,25 +31,22 @@ * to specific AdapterClient events. * Provides proxy access to Adapter functions. Converts parameters to Mojo * handles and back when necessary. - * @constructor - * @extends {cr.EventTarget} - * @param {!AdapterPtr} adapter */ - var AdapterBroker = function(adapter) { - this.adapter_ = adapter; - this.adapterClient_ = new AdapterClient(this); - this.setClient(this.adapterClient_); - }; - - AdapterBroker.prototype = { - __proto__: cr.EventTarget.prototype, + class AdapterBroker extends cr.EventTarget { + /** @param {!AdapterPtr} adapter */ + constructor(adapter) { + super(); + this.adapter_ = adapter; + this.adapterClient_ = new AdapterClient(this); + this.setClient(this.adapterClient_); + } /** * Creates a GATT connection to the device with |address|. * @param {string} address * @return {!Promise<!DevicePtr>} */ - connectToDevice: function(address) { + connectToDevice(address) { return this.adapter_.connectToDevice(address).then(function(response) { if (response.result != bluetooth.mojom.ConnectResult.SUCCESS) { // TODO(crbug.com/663394): Replace with more descriptive error @@ -64,41 +61,41 @@ return response.device; }); - }, + } /** * Gets an array of currently detectable devices from the Adapter service. * @return {!Array<!bluetooth.mojom.DeviceInfo>} */ - getDevices: function() { + getDevices() { return this.adapter_.getDevices(); - }, + } /** * Gets the current state of the Adapter. * @return {!bluetooth.mojom.AdapterInfo} */ - getInfo: function() { + getInfo() { return this.adapter_.getInfo(); - }, + } /** * Sets client of Adapter service. * @param {!bluetooth.mojom.AdapterClient} adapterClient */ - setClient: function(adapterClient) { + setClient(adapterClient) { adapterClient.binding = new mojo.Binding(bluetooth.mojom.AdapterClient, adapterClient); this.adapter_.setClient( adapterClient.binding.createInterfacePtrAndBind()); - }, + } /** * Requests the adapter to start a new discovery session. * @return {!Promise<!DiscoverySessionPtr>} */ - startDiscoverySession: function() { + startDiscoverySession() { return this.adapter_.startDiscoverySession().then(function(response) { if (!response.session.ptr.isBound()) { throw new Error('Discovery session failed to start'); @@ -106,27 +103,28 @@ return response.session; }); - }, - }; + } + } /** * The implementation of AdapterClient in * device/bluetooth/public/mojom/adapter.mojom. Dispatches events * through AdapterBroker to notify client objects of changes to the Adapter * service. - * @constructor - * @param {!AdapterBroker} adapterBroker Broker to dispatch events through. */ - var AdapterClient = function(adapterBroker) { - this.adapterBroker_ = adapterBroker; - }; + class AdapterClient { + /** + * @param {!AdapterBroker} adapterBroker Broker to dispatch events through. + */ + constructor(adapterBroker) { + this.adapterBroker_ = adapterBroker; + } - AdapterClient.prototype = { /** * Fires adapterchanged event with "present" property. * @param {boolean} present */ - presentChanged: function(present) { + presentChanged(present) { var event = new CustomEvent('adapterchanged', { detail: { property: AdapterProperty.PRESENT, @@ -134,13 +132,13 @@ } }); this.adapterBroker_.dispatchEvent(event); - }, + } /** * Fires adapterchanged event with "powered" property changed. * @param {boolean} powered */ - poweredChanged: function(powered) { + poweredChanged(powered) { var event = new CustomEvent('adapterchanged', { detail: { property: AdapterProperty.POWERED, @@ -148,13 +146,13 @@ } }); this.adapterBroker_.dispatchEvent(event); - }, + } /** * Fires adapterchanged event with "discoverable" property changed. * @param {boolean} discoverable */ - discoverableChanged: function(discoverable) { + discoverableChanged(discoverable) { var event = new CustomEvent('adapterchanged', { detail: { property: AdapterProperty.DISCOVERABLE, @@ -162,13 +160,13 @@ } }); this.adapterBroker_.dispatchEvent(event); - }, + } /** * Fires adapterchanged event with "discovering" property changed. * @param {boolean} discovering */ - discoveringChanged: function(discovering) { + discoveringChanged(discovering) { var event = new CustomEvent('adapterchanged', { detail: { property: AdapterProperty.DISCOVERING, @@ -176,38 +174,38 @@ } }); this.adapterBroker_.dispatchEvent(event); - }, + } /** * Fires deviceadded event. * @param {!bluetooth.mojom.DeviceInfo} deviceInfo */ - deviceAdded: function(deviceInfo) { + deviceAdded(deviceInfo) { var event = new CustomEvent('deviceadded', {detail: {deviceInfo: deviceInfo}}); this.adapterBroker_.dispatchEvent(event); - }, + } /** * Fires devicechanged event. * @param {!bluetooth.mojom.DeviceInfo} deviceInfo */ - deviceChanged: function(deviceInfo) { + deviceChanged(deviceInfo) { var event = new CustomEvent('devicechanged', {detail: {deviceInfo: deviceInfo}}); this.adapterBroker_.dispatchEvent(event); - }, + } /** * Fires deviceremoved event. * @param {!bluetooth.mojom.DeviceInfo} deviceInfo */ - deviceRemoved: function(deviceInfo) { + deviceRemoved(deviceInfo) { var event = new CustomEvent('deviceremoved', {detail: {deviceInfo: deviceInfo}}); this.adapterBroker_.dispatchEvent(event); - }, - }; + } + } var adapterBroker = null;
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_optin.js b/chrome/browser/resources/chromeos/assistant_optin/assistant_optin.js index 3ad7963a..b6df77a 100644 --- a/chrome/browser/resources/chromeos/assistant_optin/assistant_optin.js +++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_optin.js
@@ -15,9 +15,10 @@ /** * Starts the assistant opt-in flow. + * @param {number} type The type of the flow. */ - show: function() { - $('assistant-optin-flow-card').onShow(); + show: function(type) { + $('assistant-optin-flow-card').onShow(type); }, /** @@ -59,5 +60,6 @@ }); document.addEventListener('DOMContentLoaded', function() { - login.AssistantOptInFlowScreen.show(); + var url = new URL(document.URL); + login.AssistantOptInFlowScreen.show(url.searchParams.get('flow-type')); });
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_optin_flow.js b/chrome/browser/resources/chromeos/assistant_optin/assistant_optin_flow.js index a4e166ee..22db18b 100644 --- a/chrome/browser/resources/chromeos/assistant_optin/assistant_optin_flow.js +++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_optin_flow.js
@@ -23,17 +23,40 @@ behaviors: [OobeDialogHostBehavior], /** - * Signal from host to show the screen. + * Indicates the type of the opt-in flow. */ - onShow: function() { + FlowType: { + // The whole consent flow. + CONSENT_FLOW: 0, + // The voice match enrollment flow. + SPEAKER_ID_ENROLLMENT: 1, + }, + + /** + * Signal from host to show the screen. + * @param {number} type The type of the flow. + */ + onShow: function(type) { + this.flowType = Number(type); + if (this.flowType == NaN) { + console.error('Invalid flow type.'); + } + this.boundShowLoadingScreen = this.showLoadingScreen.bind(this); this.boundOnScreenLoadingError = this.onScreenLoadingError.bind(this); this.boundOnScreenLoaded = this.onScreenLoaded.bind(this); this.$['loading'].onBeforeShow(); this.$['loading'].addEventListener('reload', this.onReload.bind(this)); - this.showScreen(this.$['value-prop']); - chrome.send('login.AssistantOptInFlowScreen.initialized'); + + switch (this.flowType) { + case this.FlowType.SPEAKER_ID_ENROLLMENT: + this.showScreen(this.$['voice-match']); + break; + default: + this.showScreen(this.$['value-prop']); + } + chrome.send('login.AssistantOptInFlowScreen.initialized', [this.flowType]); }, /** @@ -42,6 +65,7 @@ */ reloadContent: function(data) { this.voiceMatchFeatureEnabled = data['voiceMatchFeatureEnabled']; + data['flowType'] = this.flowType; this.$['value-prop'].reloadContent(data); this.$['third-party'].reloadContent(data); this.$['get-more'].reloadContent(data); @@ -84,7 +108,11 @@ } break; case this.$['voice-match']: - this.showScreen(this.$['get-more']); + if (this.flowType == this.FlowType.SPEAKER_ID_ENROLLMENT) { + chrome.send('login.AssistantOptInFlowScreen.flowFinished'); + } else { + this.showScreen(this.$['get-more']); + } break; case this.$['get-more']: this.showScreen(this.$['ready']);
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.css b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.css index 67c1c78..cad5550a 100644 --- a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.css +++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.css
@@ -16,8 +16,9 @@ padding-top: 48px; } -#voice-match-img { - padding: 48px 0 0 48px; +#voice-match-video { + padding-top: 100px; + text-align: center; } #intro-container,
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html index bea5471..60d9200 100644 --- a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html +++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.html
@@ -18,7 +18,11 @@ <div class="title" i18n-content="assistantVoiceMatchTitle"></div> <div class="content" i18n-content="assistantVoiceMatchMessage"> </div> - <img id="voice-match-img" src="assistant_voice_match.png"> + <div id="voice-match-video"> + <video muted autoplay loop> + <source src="voice_laptop_1x.webm" type="video/webm"> + </video> + </div> </div> <div id="recording-container"> <div class="title" id="title-recording"
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.png b/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.png deleted file mode 100644 index 44b60ec..0000000 --- a/chrome/browser/resources/chromeos/assistant_optin/assistant_voice_match.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/chromeos/assistant_optin/voice_laptop_1x.webm b/chrome/browser/resources/chromeos/assistant_optin/voice_laptop_1x.webm new file mode 100644 index 0000000..2d4af89 --- /dev/null +++ b/chrome/browser/resources/chromeos/assistant_optin/voice_laptop_1x.webm Binary files differ
diff --git a/chrome/browser/resources/discards/database_tab.js b/chrome/browser/resources/discards/database_tab.js index 3ea4519b..9c814c02 100644 --- a/chrome/browser/resources/discards/database_tab.js +++ b/chrome/browser/resources/discards/database_tab.js
@@ -272,7 +272,7 @@ // Add any new origins to the (monotonically increasing) // set of requested origins. const dbRows = response.result.dbRows; - for (let dbRow of dbRows) + for (const dbRow of dbRows) this.requestedOrigins_[dbRow.origin] = true; this.rows_ = dbRows; });
diff --git a/chrome/browser/resources/discards/discards.js b/chrome/browser/resources/discards/discards.js index 78dd328f..28058248 100644 --- a/chrome/browser/resources/discards/discards.js +++ b/chrome/browser/resources/discards/discards.js
@@ -61,7 +61,7 @@ } // Hours and minutes. - let hours = Math.floor(seconds / SECONDS_PER_HOUR); + const hours = Math.floor(seconds / SECONDS_PER_HOUR); minutes = minutes % MINUTES_PER_HOUR; if (hours < HOURS_PER_DAY) { let s = hours.toString() + maybeMakePlural(' hour', hours); @@ -72,21 +72,21 @@ } // Days. - let days = Math.floor(seconds / SECONDS_PER_DAY); + const days = Math.floor(seconds / SECONDS_PER_DAY); if (days < DAYS_PER_WEEK) { return days.toString() + maybeMakePlural(' day', days); } // Weeks. There's an awkward gap to bridge where 4 weeks can have // elapsed but not quite 1 month. Be sure to use weeks to report that. - let weeks = Math.floor(seconds / SECONDS_PER_WEEK); - let months = Math.floor(seconds / SECONDS_PER_MONTH); + const weeks = Math.floor(seconds / SECONDS_PER_WEEK); + const months = Math.floor(seconds / SECONDS_PER_MONTH); if (months < 1) { return 'over ' + weeks.toString() + maybeMakePlural(' week', weeks); } // Months. - let years = Math.floor(seconds / SECONDS_PER_YEAR); + const years = Math.floor(seconds / SECONDS_PER_YEAR); if (years < 1) { return 'over ' + months.toString() + maybeMakePlural(' month', months); } @@ -101,7 +101,7 @@ * @return {string} An English string representing the duration. */ function durationToString(secondsAgo) { - let ret = secondsToString(secondsAgo); + const ret = secondsToString(secondsAgo); if (ret.endsWith(' seconds') || ret.endsWith(' second')) return 'just now';
diff --git a/chrome/browser/resources/discards/sorted_table_behavior.js b/chrome/browser/resources/discards/sorted_table_behavior.js index f08b3eec..8542c8a 100644 --- a/chrome/browser/resources/discards/sorted_table_behavior.js +++ b/chrome/browser/resources/discards/sorted_table_behavior.js
@@ -43,7 +43,7 @@ */ onSortClick: function(e) { // Remove the presentation style on the old sort header. - let oldElement = this.$$('.sort-column, .sort-column-reverse'); + const oldElement = this.$$('.sort-column, .sort-column-reverse'); if (oldElement) { oldElement.classList.remove('sort-column'); oldElement.classList.remove('sort-column-reverse');
diff --git a/chrome/browser/resources/gaia_auth_host/authenticator.js b/chrome/browser/resources/gaia_auth_host/authenticator.js index 059311d..2c0a7e3 100644 --- a/chrome/browser/resources/gaia_auth_host/authenticator.js +++ b/chrome/browser/resources/gaia_auth_host/authenticator.js
@@ -115,814 +115,826 @@ /** * Initializes the authenticator component. - * @param {webview|string} webview The webview element or its ID to host IdP - * web pages. - * @constructor */ - function Authenticator(webview) { - this.isLoaded_ = false; - this.email_ = null; - this.password_ = null; - this.gaiaId_ = null, this.sessionIndex_ = null; - this.chooseWhatToSync_ = false; - this.skipForNow_ = false; - this.authFlow = AuthFlow.DEFAULT; - this.authDomain = ''; - this.videoEnabled = false; - this.idpOrigin_ = null; - this.continueUrl_ = null; - this.continueUrlWithoutParams_ = null; - this.initialFrameUrl_ = null; - this.reloadUrl_ = null; - this.trusted_ = true; - this.readyFired_ = false; - this.webviewEventManager_ = WebviewEventManager.create(); - - this.clientId_ = null; - - this.confirmPasswordCallback = null; - this.noPasswordCallback = null; - this.insecureContentBlockedCallback = null; - this.samlApiUsedCallback = null; - this.missingGaiaInfoCallback = null; + class Authenticator extends cr.EventTarget { /** - * 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, string, function(boolean))} Arguments are the - * e-mail, the GAIA ID, and the response callback. + * @param {webview|string} webview The webview element or its ID to host + * IdP web pages. */ - this.getIsSamlUserPasswordlessCallback = null; - this.needPassword = true; - this.services_ = null; - /** - * Caches the result of |getIsSamlUserPasswordlessCallback| invocation for - * the current user. Null if no result is obtained yet. - * @type {?boolean} - * @private - */ - this.isSamlUserPasswordless_ = null; + constructor(webview) { + super(); - this.bindToWebview_(webview); + this.isLoaded_ = false; + this.email_ = null; + this.password_ = null; + this.gaiaId_ = null, this.sessionIndex_ = null; + this.chooseWhatToSync_ = false; + this.skipForNow_ = false; + this.authFlow = AuthFlow.DEFAULT; + this.authDomain = ''; + this.videoEnabled = false; + this.idpOrigin_ = null; + this.continueUrl_ = null; + this.continueUrlWithoutParams_ = null; + this.initialFrameUrl_ = null; + this.reloadUrl_ = null; + this.trusted_ = true; + this.readyFired_ = false; + this.webviewEventManager_ = WebviewEventManager.create(); - window.addEventListener( - 'message', this.onMessageFromWebview_.bind(this), false); - window.addEventListener('focus', this.onFocus_.bind(this), false); - window.addEventListener('popstate', this.onPopState_.bind(this), false); - } + this.clientId_ = null; - Authenticator.prototype = Object.create(cr.EventTarget.prototype); + this.confirmPasswordCallback = null; + this.noPasswordCallback = null; + this.insecureContentBlockedCallback = null; + this.samlApiUsedCallback = null; + this.missingGaiaInfoCallback = null; + /** + * 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, string, function(boolean))} Arguments are the + * e-mail, the GAIA ID, and the response callback. + */ + this.getIsSamlUserPasswordlessCallback = null; + this.needPassword = true; + this.services_ = null; + /** + * Caches the result of |getIsSamlUserPasswordlessCallback| invocation for + * the current user. Null if no result is obtained yet. + * @type {?boolean} + * @private + */ + this.isSamlUserPasswordless_ = null; - /** - * Reinitializes authentication parameters so that a failed login attempt - * would not result in an infinite loop. - */ - Authenticator.prototype.resetStates = function() { - this.isLoaded_ = false; - this.email_ = null; - this.gaiaId_ = null; - this.password_ = null; - this.readyFired_ = false; - this.chooseWhatToSync_ = false; - this.skipForNow_ = false; - this.sessionIndex_ = null; - this.trusted_ = true; - this.authFlow = AuthFlow.DEFAULT; - this.samlHandler_.reset(); - this.videoEnabled = false; - this.services_ = null; - this.isSamlUserPasswordless_ = null; - }; + this.bindToWebview_(webview); - /** - * Resets the webview to the blank page. - */ - Authenticator.prototype.resetWebview = function() { - if (this.webview_.src && this.webview_.src != BLANK_PAGE_URL) - this.webview_.src = BLANK_PAGE_URL; - }; - - /** - * Binds this authenticator to the passed webview. - * @param {!Object} webview the new webview to be used by this Authenticator. - * @private - */ - Authenticator.prototype.bindToWebview_ = function(webview) { - assert(!this.webview_); - assert(!this.samlHandler_); - - this.webview_ = typeof webview == 'string' ? $(webview) : webview; - - this.samlHandler_ = new cr.login.SamlHandler(this.webview_); - this.webviewEventManager_.addEventListener( - this.samlHandler_, 'insecureContentBlocked', - this.onInsecureContentBlocked_.bind(this)); - this.webviewEventManager_.addEventListener( - this.samlHandler_, 'authPageLoaded', this.onAuthPageLoaded_.bind(this)); - this.webviewEventManager_.addEventListener( - this.samlHandler_, 'videoEnabled', this.onVideoEnabled_.bind(this)); - this.webviewEventManager_.addEventListener( - this.samlHandler_, 'apiPasswordAdded', - this.onSamlApiPasswordAdded_.bind(this)); - - this.webviewEventManager_.addEventListener( - this.webview_, 'droplink', this.onDropLink_.bind(this)); - this.webviewEventManager_.addEventListener( - this.webview_, 'newwindow', this.onNewWindow_.bind(this)); - this.webviewEventManager_.addEventListener( - this.webview_, 'contentload', this.onContentLoad_.bind(this)); - this.webviewEventManager_.addEventListener( - this.webview_, 'loadabort', this.onLoadAbort_.bind(this)); - this.webviewEventManager_.addEventListener( - this.webview_, 'loadcommit', this.onLoadCommit_.bind(this)); - - this.webviewEventManager_.addWebRequestEventListener( - this.webview_.request.onCompleted, this.onRequestCompleted_.bind(this), - {urls: ['<all_urls>'], types: ['main_frame']}, ['responseHeaders']); - this.webviewEventManager_.addWebRequestEventListener( - this.webview_.request.onHeadersReceived, - this.onHeadersReceived_.bind(this), - {urls: ['<all_urls>'], types: ['main_frame', 'xmlhttprequest']}, - ['responseHeaders']); - }; - - /** - * Unbinds this Authenticator from the currently bound webview. - * @private - */ - Authenticator.prototype.unbindFromWebview_ = function() { - assert(this.webview_); - assert(this.samlHandler_); - - this.webviewEventManager_.removeAllListeners(); - - this.webview_ = undefined; - this.samlHandler_.unbindFromWebview(); - this.samlHandler_ = undefined; - }; - - /** - * Re-binds to another webview. - * @param {Object} webview the new webview to be used by this Authenticator. - */ - Authenticator.prototype.rebindWebview = function(webview) { - this.unbindFromWebview_(); - this.bindToWebview_(webview); - }; - - /** - * Loads the authenticator component with the given parameters. - * @param {AuthMode} authMode Authorization mode. - * @param {Object} data Parameters for the authorization flow. - */ - Authenticator.prototype.load = function(authMode, data) { - this.authMode = authMode; - this.resetStates(); - // gaiaUrl parameter is used for testing. Once defined, it is never changed. - this.idpOrigin_ = data.gaiaUrl || IDP_ORIGIN; - this.continueUrl_ = data.continueUrl || CONTINUE_URL; - this.continueUrlWithoutParams_ = - this.continueUrl_.substring(0, this.continueUrl_.indexOf('?')) || - this.continueUrl_; - this.isConstrainedWindow_ = data.constrained == '1'; - this.isNewGaiaFlow = data.isNewGaiaFlow; - this.clientId_ = data.clientId; - this.dontResizeNonEmbeddedPages = data.dontResizeNonEmbeddedPages; - this.chromeOSApiVersion_ = data.chromeOSApiVersion; - - this.initialFrameUrl_ = this.constructInitialFrameUrl_(data); - this.reloadUrl_ = data.frameUrl || this.initialFrameUrl_; - // Don't block insecure content for desktop flow because it lands on - // http. Otherwise, block insecure content as long as gaia is https. - this.samlHandler_.blockInsecureContent = - authMode != AuthMode.DESKTOP && this.idpOrigin_.startsWith('https://'); - this.needPassword = !('needPassword' in data) || data.needPassword; - - if (this.isNewGaiaFlow) { - this.webview_.contextMenus.onShow.addListener(function(e) { - e.preventDefault(); - }); + window.addEventListener( + 'message', this.onMessageFromWebview_.bind(this), false); + window.addEventListener('focus', this.onFocus_.bind(this), false); + window.addEventListener('popstate', this.onPopState_.bind(this), false); } - this.webview_.src = this.reloadUrl_; - this.isLoaded_ = true; - }; + /** + * Reinitializes authentication parameters so that a failed login attempt + * would not result in an infinite loop. + */ + resetStates() { + this.isLoaded_ = false; + this.email_ = null; + this.gaiaId_ = null; + this.password_ = null; + this.readyFired_ = false; + this.chooseWhatToSync_ = false; + this.skipForNow_ = false; + this.sessionIndex_ = null; + this.trusted_ = true; + this.authFlow = AuthFlow.DEFAULT; + this.samlHandler_.reset(); + this.videoEnabled = false; + this.services_ = null; + this.isSamlUserPasswordless_ = null; + } - Authenticator.prototype.constructChromeOSAPIUrl_ = function() { - if (this.chromeOSApiVersion_ && this.chromeOSApiVersion_ == 2) - return this.idpOrigin_ + EMBEDDED_SETUP_CHROMEOS_ENDPOINT_V2; + /** + * Resets the webview to the blank page. + */ + resetWebview() { + if (this.webview_.src && this.webview_.src != BLANK_PAGE_URL) + this.webview_.src = BLANK_PAGE_URL; + } - return this.idpOrigin_ + EMBEDDED_SETUP_CHROMEOS_ENDPOINT; - }; + /** + * Binds this authenticator to the passed webview. + * @param {!Object} webview the new webview to be used by this + * Authenticator. + * @private + */ + bindToWebview_(webview) { + assert(!this.webview_); + assert(!this.samlHandler_); - /** - * Reloads the authenticator component. - */ - Authenticator.prototype.reload = function() { - this.resetStates(); - this.webview_.src = this.reloadUrl_; - this.isLoaded_ = true; - }; + this.webview_ = typeof webview == 'string' ? $(webview) : webview; - Authenticator.prototype.constructInitialFrameUrl_ = function(data) { - if (data.doSamlRedirect) { - let url = this.idpOrigin_ + SAML_REDIRECTION_PATH; - url = appendParam(url, 'domain', data.enterpriseEnrollmentDomain); - url = appendParam( - url, 'continue', - data.gaiaUrl + 'programmatic_auth_chromeos?hl=' + data.hl + - '&scope=https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthLogin&' + - 'client_id=' + encodeURIComponent(data.clientId) + - '&access_type=offline'); + this.samlHandler_ = new cr.login.SamlHandler(this.webview_); + this.webviewEventManager_.addEventListener( + this.samlHandler_, 'insecureContentBlocked', + this.onInsecureContentBlocked_.bind(this)); + this.webviewEventManager_.addEventListener( + this.samlHandler_, 'authPageLoaded', + this.onAuthPageLoaded_.bind(this)); + this.webviewEventManager_.addEventListener( + this.samlHandler_, 'videoEnabled', this.onVideoEnabled_.bind(this)); + this.webviewEventManager_.addEventListener( + this.samlHandler_, 'apiPasswordAdded', + this.onSamlApiPasswordAdded_.bind(this)); + this.webviewEventManager_.addEventListener( + this.webview_, 'droplink', this.onDropLink_.bind(this)); + this.webviewEventManager_.addEventListener( + this.webview_, 'newwindow', this.onNewWindow_.bind(this)); + this.webviewEventManager_.addEventListener( + this.webview_, 'contentload', this.onContentLoad_.bind(this)); + this.webviewEventManager_.addEventListener( + this.webview_, 'loadabort', this.onLoadAbort_.bind(this)); + this.webviewEventManager_.addEventListener( + this.webview_, 'loadcommit', this.onLoadCommit_.bind(this)); + + this.webviewEventManager_.addWebRequestEventListener( + this.webview_.request.onCompleted, + this.onRequestCompleted_.bind(this), + {urls: ['<all_urls>'], types: ['main_frame']}, ['responseHeaders']); + this.webviewEventManager_.addWebRequestEventListener( + this.webview_.request.onHeadersReceived, + this.onHeadersReceived_.bind(this), + {urls: ['<all_urls>'], types: ['main_frame', 'xmlhttprequest']}, + ['responseHeaders']); + } + + /** + * Unbinds this Authenticator from the currently bound webview. + * @private + */ + unbindFromWebview_() { + assert(this.webview_); + assert(this.samlHandler_); + + this.webviewEventManager_.removeAllListeners(); + + this.webview_ = undefined; + this.samlHandler_.unbindFromWebview(); + this.samlHandler_ = undefined; + } + + /** + * Re-binds to another webview. + * @param {Object} webview the new webview to be used by this Authenticator. + */ + rebindWebview(webview) { + this.unbindFromWebview_(); + this.bindToWebview_(webview); + } + + /** + * Loads the authenticator component with the given parameters. + * @param {AuthMode} authMode Authorization mode. + * @param {Object} data Parameters for the authorization flow. + */ + load(authMode, data) { + this.authMode = authMode; + this.resetStates(); + // gaiaUrl parameter is used for testing. Once defined, it is never + // changed. + this.idpOrigin_ = data.gaiaUrl || IDP_ORIGIN; + this.continueUrl_ = data.continueUrl || CONTINUE_URL; + this.continueUrlWithoutParams_ = + this.continueUrl_.substring(0, this.continueUrl_.indexOf('?')) || + this.continueUrl_; + this.isConstrainedWindow_ = data.constrained == '1'; + this.isNewGaiaFlow = data.isNewGaiaFlow; + this.clientId_ = data.clientId; + this.dontResizeNonEmbeddedPages = data.dontResizeNonEmbeddedPages; + this.chromeOSApiVersion_ = data.chromeOSApiVersion; + + this.initialFrameUrl_ = this.constructInitialFrameUrl_(data); + this.reloadUrl_ = data.frameUrl || this.initialFrameUrl_; + // Don't block insecure content for desktop flow because it lands on + // http. Otherwise, block insecure content as long as gaia is https. + this.samlHandler_.blockInsecureContent = authMode != AuthMode.DESKTOP && + this.idpOrigin_.startsWith('https://'); + this.needPassword = !('needPassword' in data) || data.needPassword; + + if (this.isNewGaiaFlow) { + this.webview_.contextMenus.onShow.addListener(function(e) { + e.preventDefault(); + }); + } + + this.webview_.src = this.reloadUrl_; + this.isLoaded_ = true; + } + + constructChromeOSAPIUrl_() { + if (this.chromeOSApiVersion_ && this.chromeOSApiVersion_ == 2) + return this.idpOrigin_ + EMBEDDED_SETUP_CHROMEOS_ENDPOINT_V2; + + return this.idpOrigin_ + EMBEDDED_SETUP_CHROMEOS_ENDPOINT; + } + + /** + * Reloads the authenticator component. + */ + reload() { + this.resetStates(); + this.webview_.src = this.reloadUrl_; + this.isLoaded_ = true; + } + + constructInitialFrameUrl_(data) { + if (data.doSamlRedirect) { + let url = this.idpOrigin_ + SAML_REDIRECTION_PATH; + url = appendParam(url, 'domain', data.enterpriseEnrollmentDomain); + url = appendParam( + url, 'continue', + data.gaiaUrl + 'programmatic_auth_chromeos?hl=' + data.hl + + '&scope=https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthLogin&' + + 'client_id=' + encodeURIComponent(data.clientId) + + '&access_type=offline'); + + return url; + } + + let url; + if (data.gaiaPath) + url = this.idpOrigin_ + data.gaiaPath; + else if (this.isNewGaiaFlow) + url = this.constructChromeOSAPIUrl_(); + else + url = this.idpOrigin_ + IDP_PATH; + + if (this.isNewGaiaFlow) { + if (data.chromeType) + url = appendParam(url, 'chrometype', data.chromeType); + if (data.clientId) + url = appendParam(url, 'client_id', data.clientId); + if (data.enterpriseDisplayDomain) + url = appendParam(url, 'manageddomain', data.enterpriseDisplayDomain); + if (data.clientVersion) + url = appendParam(url, 'client_version', data.clientVersion); + if (data.platformVersion) + url = appendParam(url, 'platform_version', data.platformVersion); + if (data.releaseChannel) + url = appendParam(url, 'release_channel', data.releaseChannel); + if (data.endpointGen) + url = appendParam(url, 'endpoint_gen', data.endpointGen); + if (data.chromeOSApiVersion == 2) { + let mi = ''; + if (data.menuGuestMode) + mi += 'gm,'; + if (data.menuKeyboardOptions) + mi += 'ko,'; + if (data.menuEnterpriseEnrollment) + mi += 'ee,'; + if (mi.length) + url = appendParam(url, 'mi', mi); + + if (data.lsbReleaseBoard) + url = appendParam(url, 'chromeos_board', data.lsbReleaseBoard); + if (data.isFirstUser) + url = appendParam(url, 'is_first_user', true); + if (data.obfuscatedOwnerId) + url = + appendParam(url, 'obfuscated_owner_id', data.obfuscatedOwnerId); + } + } else { + url = appendParam(url, 'continue', this.continueUrl_); + url = appendParam(url, 'service', data.service || SERVICE_ID); + } + if (data.hl) + url = appendParam(url, 'hl', data.hl); + if (data.gaiaId) + url = appendParam(url, 'user_id', data.gaiaId); + if (data.email) { + if (data.readOnlyEmail) { + url = appendParam(url, 'Email', data.email); + } else { + url = appendParam(url, 'email_hint', data.email); + } + } + if (this.isConstrainedWindow_) + url = appendParam(url, 'source', CONSTRAINED_FLOW_SOURCE); + if (data.flow) + url = appendParam(url, 'flow', data.flow); + if (data.emailDomain) { + url = appendParam(url, 'emaildomain', data.emailDomain); + // ChromeOS embedded signin page uses 'hd' (hosted domain) as the query + // argument to show an email domain. + url = appendParam(url, 'hd', data.emailDomain); + } return url; } - let url; - if (data.gaiaPath) - url = this.idpOrigin_ + data.gaiaPath; - else if (this.isNewGaiaFlow) - url = this.constructChromeOSAPIUrl_(); - else - url = this.idpOrigin_ + IDP_PATH; - - if (this.isNewGaiaFlow) { - if (data.chromeType) - url = appendParam(url, 'chrometype', data.chromeType); - if (data.clientId) - url = appendParam(url, 'client_id', data.clientId); - if (data.enterpriseDisplayDomain) - url = appendParam(url, 'manageddomain', data.enterpriseDisplayDomain); - if (data.clientVersion) - url = appendParam(url, 'client_version', data.clientVersion); - if (data.platformVersion) - url = appendParam(url, 'platform_version', data.platformVersion); - if (data.releaseChannel) - url = appendParam(url, 'release_channel', data.releaseChannel); - if (data.endpointGen) - url = appendParam(url, 'endpoint_gen', data.endpointGen); - if (data.chromeOSApiVersion == 2) { - let mi = ''; - if (data.menuGuestMode) - mi += 'gm,'; - if (data.menuKeyboardOptions) - mi += 'ko,'; - if (data.menuEnterpriseEnrollment) - mi += 'ee,'; - if (mi.length) - url = appendParam(url, 'mi', mi); - - if (data.lsbReleaseBoard) - url = appendParam(url, 'chromeos_board', data.lsbReleaseBoard); - if (data.isFirstUser) - url = appendParam(url, 'is_first_user', true); - if (data.obfuscatedOwnerId) - url = appendParam(url, 'obfuscated_owner_id', data.obfuscatedOwnerId); - } - } else { - url = appendParam(url, 'continue', this.continueUrl_); - url = appendParam(url, 'service', data.service || SERVICE_ID); - } - if (data.hl) - url = appendParam(url, 'hl', data.hl); - if (data.gaiaId) - url = appendParam(url, 'user_id', data.gaiaId); - if (data.email) { - if (data.readOnlyEmail) { - url = appendParam(url, 'Email', data.email); - } else { - url = appendParam(url, 'email_hint', data.email); + /** + * Dispatches the 'ready' event if it hasn't been dispatched already for the + * current content. + * @private + */ + fireReadyEvent_() { + if (!this.readyFired_) { + this.dispatchEvent(new Event('ready')); + this.readyFired_ = true; } } - if (this.isConstrainedWindow_) - url = appendParam(url, 'source', CONSTRAINED_FLOW_SOURCE); - if (data.flow) - url = appendParam(url, 'flow', data.flow); - if (data.emailDomain) { - url = appendParam(url, 'emaildomain', data.emailDomain); - // ChromeOS embedded signin page uses 'hd' (hosted domain) as the query - // argument to show an email domain. - url = appendParam(url, 'hd', data.emailDomain); - } - return url; - }; - /** - * Dispatches the 'ready' event if it hasn't been dispatched already for the - * current content. - * @private - */ - Authenticator.prototype.fireReadyEvent_ = function() { - if (!this.readyFired_) { - this.dispatchEvent(new Event('ready')); - this.readyFired_ = true; - } - }; + /** + * Invoked when a main frame request in the webview has completed. + * @private + */ + onRequestCompleted_(details) { + const currentUrl = details.url; - /** - * Invoked when a main frame request in the webview has completed. - * @private - */ - Authenticator.prototype.onRequestCompleted_ = function(details) { - const currentUrl = details.url; + if (!this.isNewGaiaFlow && + currentUrl.lastIndexOf(this.continueUrlWithoutParams_, 0) == 0) { + if (currentUrl.indexOf('ntp=1') >= 0) + this.skipForNow_ = true; - if (!this.isNewGaiaFlow && - currentUrl.lastIndexOf(this.continueUrlWithoutParams_, 0) == 0) { - if (currentUrl.indexOf('ntp=1') >= 0) - this.skipForNow_ = true; + this.maybeCompleteAuth_(); + return; + } - this.maybeCompleteAuth_(); - return; - } + if (!currentUrl.startsWith('https')) + this.trusted_ = false; - if (!currentUrl.startsWith('https')) - this.trusted_ = false; - - if (this.isConstrainedWindow_) { - let isEmbeddedPage = false; - if (this.idpOrigin_ && currentUrl.lastIndexOf(this.idpOrigin_) == 0) { - const headers = details.responseHeaders; - for (let i = 0; headers && i < headers.length; ++i) { - if (headers[i].name.toLowerCase() == EMBEDDED_FORM_HEADER) { - isEmbeddedPage = true; - break; + if (this.isConstrainedWindow_) { + let isEmbeddedPage = false; + if (this.idpOrigin_ && currentUrl.lastIndexOf(this.idpOrigin_) == 0) { + const headers = details.responseHeaders; + for (let i = 0; headers && i < headers.length; ++i) { + if (headers[i].name.toLowerCase() == EMBEDDED_FORM_HEADER) { + isEmbeddedPage = true; + break; + } } } + + // In some cases, non-embedded pages should not be resized. For + // example, on desktop when reauthenticating for purposes of unlocking + // a profile, resizing would cause a browser window to open in the + // system profile, which is not allowed. + if (!isEmbeddedPage && !this.dontResizeNonEmbeddedPages) { + this.dispatchEvent(new CustomEvent('resize', {detail: currentUrl})); + return; + } } - // In some cases, non-embedded pages should not be resized. For - // example, on desktop when reauthenticating for purposes of unlocking - // a profile, resizing would cause a browser window to open in the - // system profile, which is not allowed. - if (!isEmbeddedPage && !this.dontResizeNonEmbeddedPages) { - this.dispatchEvent(new CustomEvent('resize', {detail: currentUrl})); - return; + this.updateHistoryState_(currentUrl); + } + + /** + * Manually updates the history. Invoked upon completion of a webview + * navigation. + * @param {string} url Request URL. + * @private + */ + updateHistoryState_(url) { + if (history.state && history.state.url != url) + history.pushState({url: url}, ''); + else + history.replaceState({url: url}, ''); + } + + /** + * Invoked when the sign-in page takes focus. + * @param {object} e The focus event being triggered. + * @private + */ + onFocus_(e) { + if (this.authMode == AuthMode.DESKTOP && + document.activeElement == document.body) { + this.webview_.focus(); } } - this.updateHistoryState_(currentUrl); - }; - - /** - * Manually updates the history. Invoked upon completion of a webview - * navigation. - * @param {string} url Request URL. - * @private - */ - Authenticator.prototype.updateHistoryState_ = function(url) { - if (history.state && history.state.url != url) - history.pushState({url: url}, ''); - else - history.replaceState({url: url}, ''); - }; - - /** - * Invoked when the sign-in page takes focus. - * @param {object} e The focus event being triggered. - * @private - */ - Authenticator.prototype.onFocus_ = function(e) { - if (this.authMode == AuthMode.DESKTOP && - document.activeElement == document.body) { - this.webview_.focus(); + /** + * Invoked when the history state is changed. + * @param {object} e The popstate event being triggered. + * @private + */ + onPopState_(e) { + const state = e.state; + if (state && state.url) + this.webview_.src = state.url; } - }; - /** - * Invoked when the history state is changed. - * @param {object} e The popstate event being triggered. - * @private - */ - Authenticator.prototype.onPopState_ = function(e) { - const state = e.state; - if (state && state.url) - this.webview_.src = state.url; - }; + /** + * Invoked when headers are received in the main frame of the webview. It + * 1) reads the authenticated user info from a signin header, + * 2) signals the start of a saml flow upon receiving a saml header. + * @return {!Object} Modified request headers. + * @private + */ + onHeadersReceived_(details) { + const currentUrl = details.url; + if (currentUrl.lastIndexOf(this.idpOrigin_, 0) != 0) + return; - /** - * Invoked when headers are received in the main frame of the webview. It - * 1) reads the authenticated user info from a signin header, - * 2) signals the start of a saml flow upon receiving a saml header. - * @return {!Object} Modified request headers. - * @private - */ - Authenticator.prototype.onHeadersReceived_ = function(details) { - const currentUrl = details.url; - if (currentUrl.lastIndexOf(this.idpOrigin_, 0) != 0) - return; + const headers = details.responseHeaders; + for (let i = 0; headers && i < headers.length; ++i) { + const header = headers[i]; + const headerName = header.name.toLowerCase(); + if (headerName == SIGN_IN_HEADER) { + const headerValues = header.value.toLowerCase().split(','); + const signinDetails = {}; + headerValues.forEach(function(e) { + const pair = e.split('='); + signinDetails[pair[0].trim()] = pair[1].trim(); + }); + // Removes "" around. + this.email_ = signinDetails['email'].slice(1, -1); + this.gaiaId_ = signinDetails['obfuscatedid'].slice(1, -1); + this.sessionIndex_ = signinDetails['sessionindex']; + this.isSamlUserPasswordless_ = null; + } else if (headerName == LOCATION_HEADER) { + // If the "choose what to sync" checkbox was clicked, then the + // continue URL will contain a source=3 field. + const location = decodeURIComponent(header.value); + this.chooseWhatToSync_ = !!location.match(/(\?|&)source=3($|&)/); + } + } + } - const headers = details.responseHeaders; - for (let i = 0; headers && i < headers.length; ++i) { - const header = headers[i]; - const headerName = header.name.toLowerCase(); - if (headerName == SIGN_IN_HEADER) { - const headerValues = header.value.toLowerCase().split(','); - const signinDetails = {}; - headerValues.forEach(function(e) { - const pair = e.split('='); - signinDetails[pair[0].trim()] = pair[1].trim(); - }); - // Removes "" around. - this.email_ = signinDetails['email'].slice(1, -1); - this.gaiaId_ = signinDetails['obfuscatedid'].slice(1, -1); - this.sessionIndex_ = signinDetails['sessionindex']; + /** + * Returns true if given HTML5 message is received from the webview element. + * @param {object} e Payload of the received HTML5 message. + */ + isGaiaMessage(e) { + if (!this.isWebviewEvent_(e)) + return false; + + // The event origin does not have a trailing slash. + if (e.origin != + this.idpOrigin_.substring(0, this.idpOrigin_.length - 1)) { + return false; + } + + // Gaia messages must be an object with 'method' property. + if (typeof e.data != 'object' || !e.data.hasOwnProperty('method')) { + return false; + } + return true; + } + + /** + * Invoked when an HTML5 message is received from the webview element. + * @param {object} e Payload of the received HTML5 message. + * @private + */ + onMessageFromWebview_(e) { + if (!this.isGaiaMessage(e)) + return; + + const msg = e.data; + if (msg.method == 'attemptLogin') { + this.email_ = msg.email; + if (this.authMode == AuthMode.DESKTOP) + this.password_ = msg.password; this.isSamlUserPasswordless_ = null; - } else if (headerName == LOCATION_HEADER) { - // If the "choose what to sync" checkbox was clicked, then the continue - // URL will contain a source=3 field. - const location = decodeURIComponent(header.value); - this.chooseWhatToSync_ = !!location.match(/(\?|&)source=3($|&)/); + + this.chooseWhatToSync_ = msg.chooseWhatToSync; + // We need to dispatch only first event, before user enters password. + this.dispatchEvent( + new CustomEvent('attemptLogin', {detail: msg.email})); + } else if (msg.method == 'dialogShown') { + this.dispatchEvent(new Event('dialogShown')); + } else if (msg.method == 'dialogHidden') { + this.dispatchEvent(new Event('dialogHidden')); + } else if (msg.method == 'backButton') { + this.dispatchEvent(new CustomEvent('backButton', {detail: msg.show})); + } else if (msg.method == 'showView') { + this.dispatchEvent(new Event('showView')); + } else if (msg.method == 'menuItemClicked') { + this.dispatchEvent( + new CustomEvent('menuItemClicked', {detail: msg.item})); + } else if (msg.method == 'identifierEntered') { + this.dispatchEvent(new CustomEvent( + 'identifierEntered', + {detail: {accountIdentifier: msg.accountIdentifier}})); + } else if (msg.method == 'userInfo') { + this.services_ = msg.services; + if (this.email_ && this.gaiaId_ && this.sessionIndex_) + this.maybeCompleteAuth_(); + } else { + console.warn('Unrecognized message from GAIA: ' + msg.method); } } - }; - /** - * Returns true if given HTML5 message is received from the webview element. - * @param {object} e Payload of the received HTML5 message. - */ - Authenticator.prototype.isGaiaMessage = function(e) { - if (!this.isWebviewEvent_(e)) - return false; - - // The event origin does not have a trailing slash. - if (e.origin != this.idpOrigin_.substring(0, this.idpOrigin_.length - 1)) { - return false; - } - - // Gaia messages must be an object with 'method' property. - if (typeof e.data != 'object' || !e.data.hasOwnProperty('method')) { - return false; - } - return true; - }; - - /** - * Invoked when an HTML5 message is received from the webview element. - * @param {object} e Payload of the received HTML5 message. - * @private - */ - Authenticator.prototype.onMessageFromWebview_ = function(e) { - if (!this.isGaiaMessage(e)) - return; - - const msg = e.data; - if (msg.method == 'attemptLogin') { - this.email_ = msg.email; - if (this.authMode == AuthMode.DESKTOP) - this.password_ = msg.password; - this.isSamlUserPasswordless_ = null; - - this.chooseWhatToSync_ = msg.chooseWhatToSync; - // We need to dispatch only first event, before user enters password. - this.dispatchEvent(new CustomEvent('attemptLogin', {detail: msg.email})); - } else if (msg.method == 'dialogShown') { - this.dispatchEvent(new Event('dialogShown')); - } else if (msg.method == 'dialogHidden') { - this.dispatchEvent(new Event('dialogHidden')); - } else if (msg.method == 'backButton') { - this.dispatchEvent(new CustomEvent('backButton', {detail: msg.show})); - } else if (msg.method == 'showView') { - this.dispatchEvent(new Event('showView')); - } else if (msg.method == 'menuItemClicked') { - this.dispatchEvent( - new CustomEvent('menuItemClicked', {detail: msg.item})); - } else if (msg.method == 'identifierEntered') { - this.dispatchEvent(new CustomEvent( - 'identifierEntered', - {detail: {accountIdentifier: msg.accountIdentifier}})); - } else if (msg.method == 'userInfo') { - this.services_ = msg.services; - if (this.email_ && this.gaiaId_ && this.sessionIndex_) - this.maybeCompleteAuth_(); - } else { - console.warn('Unrecognized message from GAIA: ' + msg.method); - } - }; - - /** - * Invoked by the hosting page to verify the Saml password. - */ - Authenticator.prototype.verifyConfirmedPassword = function(password) { - if (!this.samlHandler_.verifyConfirmedPassword(password)) { - // Invoke confirm password callback asynchronously because the - // verification was based on messages and caller (GaiaSigninScreen) - // does not expect it to be called immediately. - // TODO(xiyuan): Change to synchronous call when iframe based code - // is removed. - const invokeConfirmPassword = - (function() { - this.confirmPasswordCallback( - this.email_, this.samlHandler_.scrapedPasswordCount); - }).bind(this); - window.setTimeout(invokeConfirmPassword, 0); - return; - } - - this.password_ = password; - this.onAuthCompleted_(); - }; - - /** - * Check Saml flow and start password confirmation flow if needed. Otherwise, - * continue with auto completion. - * @private - */ - Authenticator.prototype.maybeCompleteAuth_ = function() { - const missingGaiaInfo = - !this.email_ || !this.gaiaId_ || !this.sessionIndex_; - if (missingGaiaInfo && !this.skipForNow_) { - if (this.missingGaiaInfoCallback) - this.missingGaiaInfoCallback(); - - this.webview_.src = this.initialFrameUrl_; - return; - } - // TODO(https://crbug.com/837107): remove this once API is fully stabilized. - // @example.com is used in tests. - if (!this.services_ && !this.email_.endsWith('@gmail.com') && - !this.email_.endsWith('@example.com')) { - console.warn('Forcing empty services.'); - this.services_ = []; - } - if (!this.services_) - return; - - if (this.isSamlUserPasswordless_ === null && - 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.gaiaId_, - this.onGotIsSamlUserPasswordless_.bind( - this, this.email_, this.gaiaId_)); - return; - } - - if (this.isSamlUserPasswordless_ && this.authFlow == AuthFlow.SAML && - this.email_ && this.gaiaId_) { - // No password needed for this user, so complete immediately. - this.onAuthCompleted_(); - return; - } - - if (this.samlHandler_.samlApiUsed) { - if (this.samlApiUsedCallback) { - this.samlApiUsedCallback(); - } - this.password_ = this.samlHandler_.apiPasswordBytes; - this.onAuthCompleted_(); - return; - } - - if (this.samlHandler_.scrapedPasswordCount == 0) { - if (this.noPasswordCallback) { - this.noPasswordCallback(this.email_); + /** + * Invoked by the hosting page to verify the Saml password. + */ + verifyConfirmedPassword(password) { + if (!this.samlHandler_.verifyConfirmedPassword(password)) { + // Invoke confirm password callback asynchronously because the + // verification was based on messages and caller (GaiaSigninScreen) + // does not expect it to be called immediately. + // TODO(xiyuan): Change to synchronous call when iframe based code + // is removed. + const invokeConfirmPassword = + (function() { + this.confirmPasswordCallback( + this.email_, this.samlHandler_.scrapedPasswordCount); + }).bind(this); + window.setTimeout(invokeConfirmPassword, 0); return; } - // Fall through to finish the auth flow even if this.needPassword - // is true. This is because the flag is used as an intention to get - // password when it is available but not a mandatory requirement. - console.warn('Authenticator: No password scraped for SAML.'); - } else if (this.needPassword) { - if (this.samlHandler_.scrapedPasswordCount == 1) { - // If we scraped exactly one password, we complete the authentication - // right away. - this.password_ = this.samlHandler_.firstScrapedPassword; + this.password_ = password; + this.onAuthCompleted_(); + } + + /** + * Check Saml flow and start password confirmation flow if needed. + * Otherwise, continue with auto completion. + * @private + */ + maybeCompleteAuth_() { + const missingGaiaInfo = + !this.email_ || !this.gaiaId_ || !this.sessionIndex_; + if (missingGaiaInfo && !this.skipForNow_) { + if (this.missingGaiaInfoCallback) + this.missingGaiaInfoCallback(); + + this.webview_.src = this.initialFrameUrl_; + return; + } + // TODO(https://crbug.com/837107): remove this once API is fully + // stabilized. + // @example.com is used in tests. + if (!this.services_ && !this.email_.endsWith('@gmail.com') && + !this.email_.endsWith('@example.com')) { + console.warn('Forcing empty services.'); + this.services_ = []; + } + if (!this.services_) + return; + + if (this.isSamlUserPasswordless_ === null && + 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.gaiaId_, + this.onGotIsSamlUserPasswordless_.bind( + this, this.email_, this.gaiaId_)); + return; + } + + if (this.isSamlUserPasswordless_ && this.authFlow == AuthFlow.SAML && + this.email_ && this.gaiaId_) { + // No password needed for this user, so complete immediately. this.onAuthCompleted_(); return; } - if (this.confirmPasswordCallback) { - // Confirm scraped password. The flow follows in - // verifyConfirmedPassword. - this.confirmPasswordCallback( - this.email_, this.samlHandler_.scrapedPasswordCount); + if (this.samlHandler_.samlApiUsed) { + if (this.samlApiUsedCallback) { + this.samlApiUsedCallback(); + } + this.password_ = this.samlHandler_.apiPasswordBytes; + this.onAuthCompleted_(); return; } - } - this.onAuthCompleted_(); - }; + if (this.samlHandler_.scrapedPasswordCount == 0) { + if (this.noPasswordCallback) { + this.noPasswordCallback(this.email_); + return; + } - /** - * Invoked to complete the authentication using the password the user enters - * manually for non-principals API SAML IdPs that we couldn't scrape their - * password input. - */ - Authenticator.prototype.completeAuthWithManualPassword = function(password) { - this.password_ = password; - this.onAuthCompleted_(); - }; + // Fall through to finish the auth flow even if this.needPassword + // is true. This is because the flag is used as an intention to get + // password when it is available but not a mandatory requirement. + console.warn('Authenticator: No password scraped for SAML.'); + } else if (this.needPassword) { + if (this.samlHandler_.scrapedPasswordCount == 1) { + // If we scraped exactly one password, we complete the authentication + // right away. + this.password_ = this.samlHandler_.firstScrapedPassword; + this.onAuthCompleted_(); + return; + } - /** - * Invoked when the result of |getIsSamlUserPasswordlessCallback| arrives. - * @param {string} email - * @param {string} gaiaId - * @param {boolean} isSamlUserPasswordless - * @private - */ - Authenticator.prototype.onGotIsSamlUserPasswordless_ = function( - 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_(); - } - }; - - /** - * Invoked to process authentication completion. - * @private - */ - Authenticator.prototype.onAuthCompleted_ = function() { - assert( - this.skipForNow_ || - (this.email_ && this.gaiaId_ && this.sessionIndex_)); - // Chrome will crash on incorrect data type, so log some error message here. - if (this.services_) { - if (!Array.isArray(this.services_)) { - console.error('FATAL: Bad services type:' + typeof this.services_); - } else { - for (let i = 0; i < this.services_.length; ++i) { - if (typeof this.services_[i] == 'string') - continue; - - console.error( - 'FATAL: Bad services[' + i + - '] type:' + typeof this.services_[i]); + if (this.confirmPasswordCallback) { + // Confirm scraped password. The flow follows in + // verifyConfirmedPassword. + this.confirmPasswordCallback( + this.email_, this.samlHandler_.scrapedPasswordCount); + return; } } + + this.onAuthCompleted_(); } - if (this.isSamlUserPasswordless_ && this.authFlow == AuthFlow.SAML && - this.email_) { - // In the passwordless case, the user data will be protected by non - // password based mechanisms. Clear anything that got collected into - // |password_|, if any. - this.password_ = ''; + + /** + * Invoked to complete the authentication using the password the user enters + * manually for non-principals API SAML IdPs that we couldn't scrape their + * password input. + */ + completeAuthWithManualPassword(password) { + this.password_ = password; + this.onAuthCompleted_(); } - this.dispatchEvent(new CustomEvent( - 'authCompleted', - // TODO(rsorokin): get rid of the stub values. - { - detail: { - email: this.email_ || '', - gaiaId: this.gaiaId_ || '', - password: this.password_ || '', - usingSAML: this.authFlow == AuthFlow.SAML, - chooseWhatToSync: this.chooseWhatToSync_, - skipForNow: this.skipForNow_, - sessionIndex: this.sessionIndex_ || '', - trusted: this.trusted_, - services: this.services_ || [], + + /** + * Invoked when the result of |getIsSamlUserPasswordlessCallback| arrives. + * @param {string} email + * @param {string} gaiaId + * @param {boolean} isSamlUserPasswordless + * @private + */ + onGotIsSamlUserPasswordless_(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_(); + } + } + + /** + * Invoked to process authentication completion. + * @private + */ + onAuthCompleted_() { + assert( + this.skipForNow_ || + (this.email_ && this.gaiaId_ && this.sessionIndex_)); + // Chrome will crash on incorrect data type, so log some error message + // here. + if (this.services_) { + if (!Array.isArray(this.services_)) { + console.error('FATAL: Bad services type:' + typeof this.services_); + } else { + for (let i = 0; i < this.services_.length; ++i) { + if (typeof this.services_[i] == 'string') + continue; + + console.error( + 'FATAL: Bad services[' + i + + '] type:' + typeof this.services_[i]); } - })); - this.resetStates(); - }; - - /** - * Invoked when |samlHandler_| fires 'insecureContentBlocked' event. - * @private - */ - Authenticator.prototype.onInsecureContentBlocked_ = function(e) { - if (!this.isLoaded_) - return; - - if (this.insecureContentBlockedCallback) - this.insecureContentBlockedCallback(e.detail.url); - else - console.error('Authenticator: Insecure content blocked.'); - }; - - /** - * Invoked when |samlHandler_| fires 'authPageLoaded' event. - * @private - */ - Authenticator.prototype.onAuthPageLoaded_ = function(e) { - if (!this.isLoaded_) - return; - - if (!e.detail.isSAMLPage) - return; - - this.authDomain = this.samlHandler_.authDomain; - this.authFlow = AuthFlow.SAML; - - this.webview_.focus(); - this.fireReadyEvent_(); - }; - - /** - * Invoked when |samlHandler_| fires 'videoEnabled' event. - * @private - */ - Authenticator.prototype.onVideoEnabled_ = function(e) { - this.videoEnabled = true; - }; - - /** - * Invoked when |samlHandler_| fires 'apiPasswordAdded' event. - * @private - */ - Authenticator.prototype.onSamlApiPasswordAdded_ = function(e) { - // Saml API 'add' password might be received after the 'loadcommit' event. - // In such case, maybeCompleteAuth_ should be attempted again if GAIA ID is - // available. - if (this.gaiaId_) - this.maybeCompleteAuth_(); - }; - - /** - * Invoked when a link is dropped on the webview. - * @private - */ - Authenticator.prototype.onDropLink_ = function(e) { - this.dispatchEvent(new CustomEvent('dropLink', {detail: e.url})); - }; - - /** - * Invoked when the webview attempts to open a new window. - * @private - */ - Authenticator.prototype.onNewWindow_ = function(e) { - this.dispatchEvent(new CustomEvent('newWindow', {detail: e})); - }; - - /** - * Invoked when a new document is loaded. - * @private - */ - Authenticator.prototype.onContentLoad_ = function(e) { - if (this.isConstrainedWindow_) { - // Signin content in constrained windows should not zoom. Isolate the - // webview from the zooming of other webviews using the 'per-view' zoom - // mode, and then set it to 100% zoom. - this.webview_.setZoomMode('per-view'); - this.webview_.setZoom(1); + } + } + if (this.isSamlUserPasswordless_ && this.authFlow == AuthFlow.SAML && + this.email_) { + // In the passwordless case, the user data will be protected by non + // password based mechanisms. Clear anything that got collected into + // |password_|, if any. + this.password_ = ''; + } + this.dispatchEvent(new CustomEvent( + 'authCompleted', + // TODO(rsorokin): get rid of the stub values. + { + detail: { + email: this.email_ || '', + gaiaId: this.gaiaId_ || '', + password: this.password_ || '', + usingSAML: this.authFlow == AuthFlow.SAML, + chooseWhatToSync: this.chooseWhatToSync_, + skipForNow: this.skipForNow_, + sessionIndex: this.sessionIndex_ || '', + trusted: this.trusted_, + services: this.services_ || [], + } + })); + this.resetStates(); } - // Posts a message to IdP pages to initiate communication. - const currentUrl = this.webview_.src; - if (currentUrl.lastIndexOf(this.idpOrigin_) == 0) { - const msg = { - 'method': 'handshake', - }; + /** + * Invoked when |samlHandler_| fires 'insecureContentBlocked' event. + * @private + */ + onInsecureContentBlocked_(e) { + if (!this.isLoaded_) + return; - // |this.webview_.contentWindow| may be null after network error screen - // is shown. See crbug.com/770999. - if (this.webview_.contentWindow) - this.webview_.contentWindow.postMessage(msg, currentUrl); + if (this.insecureContentBlockedCallback) + this.insecureContentBlockedCallback(e.detail.url); else - console.error('Authenticator: contentWindow is null.'); + console.error('Authenticator: Insecure content blocked.'); + } - if (this.authMode == AuthMode.DEFAULT) { - chrome.send('metricsHandler:recordBooleanHistogram', [ - 'ChromeOS.GAIA.AuthenticatorContentWindowNull', - !this.webview_.contentWindow - ]); + /** + * Invoked when |samlHandler_| fires 'authPageLoaded' event. + * @private + */ + onAuthPageLoaded_(e) { + if (!this.isLoaded_) + return; + + if (!e.detail.isSAMLPage) + return; + + this.authDomain = this.samlHandler_.authDomain; + this.authFlow = AuthFlow.SAML; + + this.webview_.focus(); + this.fireReadyEvent_(); + } + + /** + * Invoked when |samlHandler_| fires 'videoEnabled' event. + * @private + */ + onVideoEnabled_(e) { + this.videoEnabled = true; + } + + /** + * Invoked when |samlHandler_| fires 'apiPasswordAdded' event. + * @private + */ + onSamlApiPasswordAdded_(e) { + // Saml API 'add' password might be received after the 'loadcommit' event. + // In such case, maybeCompleteAuth_ should be attempted again if GAIA ID + // is available. + if (this.gaiaId_) + this.maybeCompleteAuth_(); + } + + /** + * Invoked when a link is dropped on the webview. + * @private + */ + onDropLink_(e) { + this.dispatchEvent(new CustomEvent('dropLink', {detail: e.url})); + } + + /** + * Invoked when the webview attempts to open a new window. + * @private + */ + onNewWindow_(e) { + this.dispatchEvent(new CustomEvent('newWindow', {detail: e})); + } + + /** + * Invoked when a new document is loaded. + * @private + */ + onContentLoad_(e) { + if (this.isConstrainedWindow_) { + // Signin content in constrained windows should not zoom. Isolate the + // webview from the zooming of other webviews using the 'per-view' zoom + // mode, and then set it to 100% zoom. + this.webview_.setZoomMode('per-view'); + this.webview_.setZoom(1); } - this.fireReadyEvent_(); - // Focus webview after dispatching event when webview is already visible. - this.webview_.focus(); - } else if (currentUrl == BLANK_PAGE_URL) { - this.fireReadyEvent_(); + // Posts a message to IdP pages to initiate communication. + const currentUrl = this.webview_.src; + if (currentUrl.lastIndexOf(this.idpOrigin_) == 0) { + const msg = { + 'method': 'handshake', + }; + + // |this.webview_.contentWindow| may be null after network error screen + // is shown. See crbug.com/770999. + if (this.webview_.contentWindow) + this.webview_.contentWindow.postMessage(msg, currentUrl); + else + console.error('Authenticator: contentWindow is null.'); + + if (this.authMode == AuthMode.DEFAULT) { + chrome.send('metricsHandler:recordBooleanHistogram', [ + 'ChromeOS.GAIA.AuthenticatorContentWindowNull', + !this.webview_.contentWindow + ]); + } + + this.fireReadyEvent_(); + // Focus webview after dispatching event when webview is already + // visible. + this.webview_.focus(); + } else if (currentUrl == BLANK_PAGE_URL) { + this.fireReadyEvent_(); + } } - }; - /** - * Invoked when the webview fails loading a page. - * @private - */ - Authenticator.prototype.onLoadAbort_ = function(e) { - this.dispatchEvent( - new CustomEvent('loadAbort', {detail: {error: e.reason, src: e.url}})); - }; + /** + * Invoked when the webview fails loading a page. + * @private + */ + onLoadAbort_(e) { + this.dispatchEvent(new CustomEvent( + 'loadAbort', {detail: {error: e.reason, src: e.url}})); + } - /** - * Invoked when the webview navigates withing the current document. - * @private - */ - Authenticator.prototype.onLoadCommit_ = function(e) { - if (this.gaiaId_) - this.maybeCompleteAuth_(); - }; + /** + * Invoked when the webview navigates withing the current document. + * @private + */ + onLoadCommit_(e) { + if (this.gaiaId_) + this.maybeCompleteAuth_(); + } - /** - * Returns |true| if event |e| was sent from the hosted webview. - * @private - */ - Authenticator.prototype.isWebviewEvent_ = function(e) { - // Note: <webview> prints error message to console if |contentWindow| is not - // defined. - // TODO(dzhioev): remove the message. http://crbug.com/469522 - const webviewWindow = this.webview_.contentWindow; - return !!webviewWindow && webviewWindow === e.source; - }; + /** + * Returns |true| if event |e| was sent from the hosted webview. + * @private + */ + isWebviewEvent_(e) { + // Note: <webview> prints error message to console if |contentWindow| is + // not defined. + // TODO(dzhioev): remove the message. http://crbug.com/469522 + const webviewWindow = this.webview_.contentWindow; + return !!webviewWindow && webviewWindow === e.source; + } + } /** * The current auth flow of the hosted auth page.
diff --git a/chrome/browser/resources/gaia_auth_host/saml_handler.js b/chrome/browser/resources/gaia_auth_host/saml_handler.js index 6df298e..19dbd75cb 100644 --- a/chrome/browser/resources/gaia_auth_host/saml_handler.js +++ b/chrome/browser/resources/gaia_auth_host/saml_handler.js
@@ -69,117 +69,115 @@ /** * A handler to provide saml support for the given webview that hosts the * auth IdP pages. - * @extends {cr.EventTarget} - * @param {webview} webview - * @constructor */ - function SamlHandler(webview) { - /** - * The webview that serves IdP pages. - * @type {webview} - */ - this.webview_ = webview; + class SamlHandler extends cr.EventTarget { + /** @param {webview} webview */ + constructor(webview) { + super(); - /** - * Whether a Saml IdP page is display in the webview. - * @type {boolean} - */ - this.isSamlPage_ = false; + /** + * The webview that serves IdP pages. + * @type {webview} + */ + this.webview_ = webview; - /** - * Pending Saml IdP page flag that is set when a SAML_HEADER is received - * and is copied to |isSamlPage_| in loadcommit. - * @type {boolean} - */ - this.pendingIsSamlPage_ = false; + /** + * Whether a Saml IdP page is display in the webview. + * @type {boolean} + */ + this.isSamlPage_ = false; - /** - * The last aborted top level url. It is recorded in loadabort event and - * used to skip injection into Chrome's error page in the following - * loadcommit event. - * @type {string} - */ - this.abortedTopLevelUrl_ = null; + /** + * Pending Saml IdP page flag that is set when a SAML_HEADER is received + * and is copied to |isSamlPage_| in loadcommit. + * @type {boolean} + */ + this.pendingIsSamlPage_ = false; - /** - * The domain of the Saml IdP. - * @type {string} - */ - this.authDomain = ''; + /** + * The last aborted top level url. It is recorded in loadabort event and + * used to skip injection into Chrome's error page in the following + * loadcommit event. + * @type {string} + */ + this.abortedTopLevelUrl_ = null; - /** - * Scraped password stored in an id to password field value map. - * @type {Object<string, string>} - * @private - */ - this.passwordStore_ = {}; + /** + * The domain of the Saml IdP. + * @type {string} + */ + this.authDomain = ''; - /** - * Whether Saml API is initialized. - * @type {boolean} - */ - this.apiInitialized_ = false; + /** + * Scraped password stored in an id to password field value map. + * @type {Object<string, string>} + * @private + */ + this.passwordStore_ = {}; - /** - * Saml API version to use. - * @type {number} - */ - this.apiVersion_ = 0; + /** + * Whether Saml API is initialized. + * @type {boolean} + */ + this.apiInitialized_ = false; - /** - * Saml API token received. - * @type {string} - */ - this.apiToken_ = null; + /** + * Saml API version to use. + * @type {number} + */ + this.apiVersion_ = 0; - /** - * Saml API password bytes. - * @type {string} - */ - this.apiPasswordBytes_ = null; + /** + * Saml API token received. + * @type {string} + */ + this.apiToken_ = null; - /* - * Whether to abort the authentication flow and show an error messagen when - * content served over an unencrypted connection is detected. - * @type {boolean} - */ - this.blockInsecureContent = false; + /** + * Saml API password bytes. + * @type {string} + */ + this.apiPasswordBytes_ = null; - this.webviewEventManager_ = WebviewEventManager.create(); + /* + * Whether to abort the authentication flow and show an error messagen + * when content served over an unencrypted connection is detected. + * @type {boolean} + */ + this.blockInsecureContent = false; - this.webviewEventManager_.addEventListener( - this.webview_, 'contentload', this.onContentLoad_.bind(this)); - this.webviewEventManager_.addEventListener( - this.webview_, 'loadabort', this.onLoadAbort_.bind(this)); - this.webviewEventManager_.addEventListener( - this.webview_, 'loadcommit', this.onLoadCommit_.bind(this)); - this.webviewEventManager_.addEventListener( - this.webview_, 'permissionrequest', - this.onPermissionRequest_.bind(this)); + this.webviewEventManager_ = WebviewEventManager.create(); - this.webviewEventManager_.addWebRequestEventListener( - this.webview_.request.onBeforeRequest, - this.onInsecureRequest.bind(this), - {urls: ['http://*/*', 'file://*/*', 'ftp://*/*']}, ['blocking']); - this.webviewEventManager_.addWebRequestEventListener( - this.webview_.request.onHeadersReceived, - this.onHeadersReceived_.bind(this), - {urls: ['<all_urls>'], types: ['main_frame', 'xmlhttprequest']}, - ['blocking', 'responseHeaders']); + this.webviewEventManager_.addEventListener( + this.webview_, 'contentload', this.onContentLoad_.bind(this)); + this.webviewEventManager_.addEventListener( + this.webview_, 'loadabort', this.onLoadAbort_.bind(this)); + this.webviewEventManager_.addEventListener( + this.webview_, 'loadcommit', this.onLoadCommit_.bind(this)); + this.webviewEventManager_.addEventListener( + this.webview_, 'permissionrequest', + this.onPermissionRequest_.bind(this)); - this.webview_.addContentScripts([{ - name: injectedScriptName, - matches: ['http://*/*', 'https://*/*'], - js: {code: injectedJs}, - all_frames: true, - run_at: 'document_start' - }]); + this.webviewEventManager_.addWebRequestEventListener( + this.webview_.request.onBeforeRequest, + this.onInsecureRequest.bind(this), + {urls: ['http://*/*', 'file://*/*', 'ftp://*/*']}, ['blocking']); + this.webviewEventManager_.addWebRequestEventListener( + this.webview_.request.onHeadersReceived, + this.onHeadersReceived_.bind(this), + {urls: ['<all_urls>'], types: ['main_frame', 'xmlhttprequest']}, + ['blocking', 'responseHeaders']); - PostMessageChannel.runAsDaemon(this.onConnected_.bind(this)); - } + this.webview_.addContentScripts([{ + name: injectedScriptName, + matches: ['http://*/*', 'https://*/*'], + js: {code: injectedJs}, + all_frames: true, + run_at: 'document_start' + }]); - SamlHandler.prototype = { - __proto__: cr.EventTarget.prototype, + PostMessageChannel.runAsDaemon(this.onConnected_.bind(this)); + } /** * Whether Saml API is used during auth. @@ -187,7 +185,7 @@ */ get samlApiUsed() { return !!this.apiPasswordBytes_; - }, + } /** * Returns the Saml API password bytes. @@ -195,7 +193,7 @@ */ get apiPasswordBytes() { return this.apiPasswordBytes_; - }, + } /** * Returns the first scraped password if any, or an empty string otherwise. @@ -204,7 +202,7 @@ get firstScrapedPassword() { const scraped = this.getConsolidatedScrapedPasswords_(); return scraped.length ? scraped[0] : ''; - }, + } /** * Returns the number of scraped passwords. @@ -212,35 +210,35 @@ */ get scrapedPasswordCount() { return this.getConsolidatedScrapedPasswords_().length; - }, + } /** * Gets the de-duped scraped passwords. * @return {Array<string>} * @private */ - getConsolidatedScrapedPasswords_: function() { + getConsolidatedScrapedPasswords_() { const passwords = {}; for (const property in this.passwordStore_) { passwords[this.passwordStore_[property]] = true; } return Object.keys(passwords); - }, + } /** * Removes the injected content script and unbinds all listeners from the * webview passed to the constructor. This SAMLHandler will be unusable * after this function returns. */ - unbindFromWebview: function() { + unbindFromWebview() { this.webview_.removeContentScripts([injectedScriptName]); this.webviewEventManager_.removeAllListeners(); - }, + } /** * Resets all auth states */ - reset: function() { + reset() { this.isSamlPage_ = false; this.pendingIsSamlPage_ = false; this.passwordStore_ = {}; @@ -249,43 +247,43 @@ this.apiVersion_ = 0; this.apiToken_ = null; this.apiPasswordBytes_ = null; - }, + } /** * Check whether the given |password| is in the scraped passwords. * @return {boolean} True if the |password| is found. */ - verifyConfirmedPassword: function(password) { + verifyConfirmedPassword(password) { return this.getConsolidatedScrapedPasswords_().indexOf(password) >= 0; - }, + } /** * Invoked on the webview's contentload event. * @private */ - onContentLoad_: function(e) { + onContentLoad_(e) { // |this.webview_.contentWindow| may be null after network error screen // is shown. See crbug.com/770999. if (this.webview_.contentWindow) PostMessageChannel.init(this.webview_.contentWindow); else console.error('SamlHandler.onContentLoad_: contentWindow is null.'); - }, + } /** * Invoked on the webview's loadabort event. * @private */ - onLoadAbort_: function(e) { + onLoadAbort_(e) { if (e.isTopLevel) this.abortedTopLevelUrl_ = e.url; - }, + } /** * Invoked on the webview's loadcommit event for both main and sub frames. * @private */ - onLoadCommit_: function(e) { + onLoadCommit_(e) { // Skip this loadcommit if the top level load is just aborted. if (e.isTopLevel && e.url === this.abortedTopLevelUrl_) { this.abortedTopLevelUrl_ = null; @@ -297,7 +295,7 @@ return; this.isSamlPage_ = this.pendingIsSamlPage_; - }, + } /** * Handler for webRequest.onBeforeRequest, invoked when content served over @@ -307,20 +305,20 @@ * @param {Object} details * @return {!Object} Decision whether to block the request. */ - onInsecureRequest: function(details) { + onInsecureRequest(details) { if (!this.blockInsecureContent) return {}; const strippedUrl = stripParams(details.url); this.dispatchEvent(new CustomEvent( 'insecureContentBlocked', {detail: {url: strippedUrl}})); return {cancel: true}; - }, + } /** * Invoked when headers are received for the main frame. * @private */ - onHeadersReceived_: function(details) { + onHeadersReceived_(details) { const headers = details.responseHeaders; // Check whether GAIA headers indicating the start or end of a SAML @@ -339,12 +337,12 @@ } return {}; - }, + } /** * Invoked when the injected JS makes a connection. */ - onConnected_: function(port) { + onConnected_(port) { if (port.targetWindow != this.webview_.contentWindow) return; @@ -358,9 +356,9 @@ 'pageLoaded', this.onPageLoaded_.bind(this, channel)); channel.registerMessage( 'getSAMLFlag', this.onGetSAMLFlag_.bind(this, channel)); - }, + } - sendInitializationSuccess_: function(channel) { + sendInitializationSuccess_(channel) { channel.send({ name: 'apiResponse', response: { @@ -369,12 +367,12 @@ keyTypes: API_KEY_TYPES } }); - }, + } - sendInitializationFailure_: function(channel) { + sendInitializationFailure_(channel) { channel.send( {name: 'apiResponse', response: {result: 'initialization_failed'}}); - }, + } /** * Handlers for channel messages. @@ -382,7 +380,7 @@ * @param {Object} msg Received message. * @private */ - onAPICall_: function(channel, msg) { + onAPICall_(channel, msg) { const call = msg.call; if (call.method == 'initialize') { if (!Number.isInteger(call.requestedVersion) || @@ -415,14 +413,14 @@ } else { console.error('SamlHandler.onAPICall_: unknown message'); } - }, + } - onUpdatePassword_: function(channel, msg) { + onUpdatePassword_(channel, msg) { if (this.isSamlPage_) this.passwordStore_[msg.id] = msg.password; - }, + } - onPageLoaded_: function(channel, msg) { + onPageLoaded_(channel, msg) { this.authDomain = extractDomain(msg.url); this.dispatchEvent(new CustomEvent('authPageLoaded', { detail: { @@ -431,21 +429,21 @@ domain: this.authDomain } })); - }, + } - onPermissionRequest_: function(permissionEvent) { + onPermissionRequest_(permissionEvent) { if (permissionEvent.permission === 'media') { // The actual permission check happens in // WebUILoginView::RequestMediaAccessPermission(). this.dispatchEvent(new CustomEvent('videoEnabled')); permissionEvent.request.allow(); } - }, + } - onGetSAMLFlag_: function(channel, msg) { + onGetSAMLFlag_(channel, msg) { return this.isSamlPage_; - }, - }; + } + } return {SamlHandler: SamlHandler}; });
diff --git a/chrome/browser/resources/md_bookmarks/command_manager.js b/chrome/browser/resources/md_bookmarks/command_manager.js index e573fdf..a9e4ede 100644 --- a/chrome/browser/resources/md_bookmarks/command_manager.js +++ b/chrome/browser/resources/md_bookmarks/command_manager.js
@@ -292,14 +292,14 @@ const state = this.getState(); switch (command) { case Command.EDIT: { - let id = Array.from(itemIds)[0]; + const id = Array.from(itemIds)[0]; /** @type {!BookmarksEditDialogElement} */ (this.$.editDialog.get()) .showEditDialog(state.nodes[id]); break; } case Command.COPY_URL: case Command.COPY: { - let idList = Array.from(itemIds); + const idList = Array.from(itemIds); chrome.bookmarkManagerPrivate.copy(idList, () => { let labelPromise; if (command == Command.COPY_URL) { @@ -319,7 +319,7 @@ break; } case Command.SHOW_IN_FOLDER: { - let id = Array.from(itemIds)[0]; + const id = Array.from(itemIds)[0]; this.dispatch(bookmarks.actions.selectFolder( assert(state.nodes[id].parentId), state.nodes)); bookmarks.DialogFocusManager.getInstance().clearFocus(); @@ -327,7 +327,7 @@ break; } case Command.DELETE: { - let idList = Array.from(this.minimizeDeletionSet_(itemIds)); + const idList = Array.from(this.minimizeDeletionSet_(itemIds)); const title = state.nodes[idList[0]].title; let labelPromise;
diff --git a/chrome/browser/resources/md_extensions/BUILD.gn b/chrome/browser/resources/md_extensions/BUILD.gn index 4cd2d50c..b6dad005 100644 --- a/chrome/browser/resources/md_extensions/BUILD.gn +++ b/chrome/browser/resources/md_extensions/BUILD.gn
@@ -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("//third_party/closure_compiler/compile_js.gni") -import("../optimize_webui.gni") -import("//tools/grit/grit_rule.gni") import("//chrome/common/features.gni") +import("//third_party/closure_compiler/compile_js.gni") +import("//tools/grit/grit_rule.gni") +import("../optimize_webui.gni") extensions_pak_file = "extensions_resources.pak" unpak_folder = "extensions_resources.unpak" @@ -101,6 +101,7 @@ js_library("activity_log") { deps = [ ":activity_log_item", + "//ui/webui/resources/cr_elements/cr_search_field:cr_search_field", "//ui/webui/resources/js:cr", ] externs_list = [
diff --git a/chrome/browser/resources/md_extensions/activity_log.html b/chrome/browser/resources/md_extensions/activity_log.html index 2adcd13..ab686391 100644 --- a/chrome/browser/resources/md_extensions/activity_log.html +++ b/chrome/browser/resources/md_extensions/activity_log.html
@@ -1,6 +1,7 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/cr_container_shadow_behavior.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_search_field/cr_search_field.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/promise_resolver.html"> @@ -21,8 +22,13 @@ } #activity-log-heading { + flex-grow: 1; margin-inline-start: 16px; } + + cr-search-field { + padding-inline-end: 8px; + } </style> <div class="page-container" id="container"> <div class="page-content"> @@ -32,6 +38,9 @@ on-click="onCloseButtonTap_"></button> </paper-icon-button-light> <span id="activity-log-heading">$i18n{activityLogPageHeading}</span> + <cr-search-field label="$i18n{activityLogSearchLabel}" + on-search-changed="onSearchChanged_"> + </cr-search-field > </div> <div id="loading-activities" class="activity-message" hidden$="[[!shouldShowLoadingMessage_(
diff --git a/chrome/browser/resources/md_extensions/activity_log.js b/chrome/browser/resources/md_extensions/activity_log.js index d9363f11..c40988e 100644 --- a/chrome/browser/resources/md_extensions/activity_log.js +++ b/chrome/browser/resources/md_extensions/activity_log.js
@@ -26,6 +26,13 @@ * @return {!Promise<!chrome.activityLogPrivate.ActivityResultSet>} */ getExtensionActivityLog(extensionId) {} + + /** + * @param {string} extensionId + * @param {string} searchTerm + * @return {!Promise<!chrome.activityLogPrivate.ActivityResultSet>} + */ + getFilteredExtensionActivityLog(extensionId, searchTerm) {} } /** @@ -124,6 +131,9 @@ * @type {!PromiseResolver} */ onDataFetched: {type: Object, value: new PromiseResolver()}, + + /** @private */ + lastSearch_: String, }, /** @private {?number} */ @@ -185,16 +195,55 @@ {page: Page.DETAILS, extensionId: this.extensionId}); }, + /** + * @private + * @param {!Array<!chrome.activityLogPrivate.ExtensionActivity>} + * activityData + */ + processActivities_: function(activityData) { + this.pageState_ = ActivityLogPageState.LOADED; + this.activityData_ = + sortActivitiesByCallCount(groupActivitiesByApiCall(activityData)); + if (!this.onDataFetched.isFulfilled) + this.onDataFetched.resolve(); + }, + /** @private */ getActivityLog_: function() { this.pageState_ = ActivityLogPageState.LOADING; this.delegate.getExtensionActivityLog(this.extensionId).then(result => { - this.pageState_ = ActivityLogPageState.LOADED; - this.activityData_ = sortActivitiesByCallCount( - groupActivitiesByApiCall(result.activities)); - this.onDataFetched.resolve(); + this.processActivities_(result.activities); }); }, + + /** + * @private + * @param {string} searchTerm + */ + getFilteredActivityLog_: function(searchTerm) { + this.pageState_ = ActivityLogPageState.LOADING; + this.delegate + .getFilteredExtensionActivityLog(this.extensionId, searchTerm) + .then(result => { + this.processActivities_(result.activities); + }); + }, + + /** @private */ + onSearchChanged_: function(e) { + // Remove all whitespaces from the search term, as API call names and + // urls should not contain any whitespace. As of now, only single term + // search queries are allowed. + const searchTerm = e.detail.replace(/\s+/g, ''); + if (searchTerm === this.lastSearch_) + return; + + this.lastSearch_ = searchTerm; + if (searchTerm === '') + this.getActivityLog_(); + else + this.getFilteredActivityLog_(searchTerm); + }, }); return {
diff --git a/chrome/browser/resources/md_extensions/activity_log_item.js b/chrome/browser/resources/md_extensions/activity_log_item.js index 3f49613c..f7d4038 100644 --- a/chrome/browser/resources/md_extensions/activity_log_item.js +++ b/chrome/browser/resources/md_extensions/activity_log_item.js
@@ -66,6 +66,8 @@ return Array.from(this.data.countsByUrl.entries()) .map(e => ({page: e[0], count: e[1]})) .sort(function(a, b) { + if (a.count != b.count) + return b.count - a.count; return a.page < b.page ? -1 : (a.page > b.page ? 1 : 0); }); },
diff --git a/chrome/browser/resources/md_extensions/code_section.js b/chrome/browser/resources/md_extensions/code_section.js index 001dad3..574ed76 100644 --- a/chrome/browser/resources/md_extensions/code_section.js +++ b/chrome/browser/resources/md_extensions/code_section.js
@@ -108,7 +108,7 @@ this.truncatedBefore_ = linesBefore.length - visibleLineCountBefore; this.truncatedAfter_ = linesAfter.length - visibleLineCountAfter; - let visibleCode = visibleBefore + highlight + visibleAfter; + const visibleCode = visibleBefore + highlight + visibleAfter; this.setLineNumbers_( this.truncatedBefore_ + 1,
diff --git a/chrome/browser/resources/md_extensions/drag_and_drop_handler.js b/chrome/browser/resources/md_extensions/drag_and_drop_handler.js index 1a628c9..4011c6a0 100644 --- a/chrome/browser/resources/md_extensions/drag_and_drop_handler.js +++ b/chrome/browser/resources/md_extensions/drag_and_drop_handler.js
@@ -60,7 +60,7 @@ // Files lack a check if they're a directory, but we can find out through // its item entry. - let item = e.dataTransfer.items[0]; + const item = e.dataTransfer.items[0]; if (item.kind === 'file' && item.webkitGetAsEntry().isDirectory) { handled = true; this.handleDirectoryDrop_();
diff --git a/chrome/browser/resources/md_extensions/error_page.js b/chrome/browser/resources/md_extensions/error_page.js index ea9ec3a..a0020e91 100644 --- a/chrome/browser/resources/md_extensions/error_page.js +++ b/chrome/browser/resources/md_extensions/error_page.js
@@ -353,12 +353,12 @@ e.preventDefault(); - let list = e.target.parentElement.querySelectorAll('li'); + const list = e.target.parentElement.querySelectorAll('li'); for (let i = 0; i < list.length; ++i) { if (list[i].classList.contains('selected')) { - let polymerEvent = /** @type {!{model: !Object}} */ (e); - let frame = polymerEvent.model.item.stackTrace[i + direction]; + const polymerEvent = /** @type {!{model: !Object}} */ (e); + const frame = polymerEvent.model.item.stackTrace[i + direction]; if (frame) { this.updateSelected_(frame); list[i + direction].focus(); // Preserve focus.
diff --git a/chrome/browser/resources/md_extensions/item.js b/chrome/browser/resources/md_extensions/item.js index a951f9dc..714f659 100644 --- a/chrome/browser/resources/md_extensions/item.js +++ b/chrome/browser/resources/md_extensions/item.js
@@ -339,7 +339,7 @@ * @private */ computeFirstInspectLabel_: function() { - let label = this.computeFirstInspectTitle_(); + const label = this.computeFirstInspectTitle_(); return label && this.data.views.length > 1 ? label + ',' : label; },
diff --git a/chrome/browser/resources/md_extensions/manager.js b/chrome/browser/resources/md_extensions/manager.js index 2f171ab4..1caf8a9 100644 --- a/chrome/browser/resources/md_extensions/manager.js +++ b/chrome/browser/resources/md_extensions/manager.js
@@ -166,9 +166,9 @@ /** @override */ ready: function() { - let service = extensions.Service.getInstance(); + const service = extensions.Service.getInstance(); - let onProfileStateChanged = profileInfo => { + const onProfileStateChanged = profileInfo => { this.isSupervised_ = profileInfo.isSupervised; this.incognitoAvailable_ = profileInfo.isIncognitoAvailable; this.devModeControlledByPolicy = @@ -340,10 +340,10 @@ */ initExtensionsAndApps_: function(extensionsAndApps) { extensionsAndApps.sort(compareExtensions); - let apps = []; - let extensions = []; - for (let i of extensionsAndApps) { - let list = this.getListId_(i) === 'apps_' ? apps : extensions; + const apps = []; + const extensions = []; + for (const i of extensionsAndApps) { + const list = this.getListId_(i) === 'apps_' ? apps : extensions; list.push(i); }
diff --git a/chrome/browser/resources/md_extensions/navigation_helper.js b/chrome/browser/resources/md_extensions/navigation_helper.js index 91ed6ff..1222892 100644 --- a/chrome/browser/resources/md_extensions/navigation_helper.js +++ b/chrome/browser/resources/md_extensions/navigation_helper.js
@@ -151,7 +151,7 @@ * @param {!PageState} newPage the page to navigate to. */ navigateTo(newPage) { - let currentPage = this.getCurrentPage(); + const currentPage = this.getCurrentPage(); if (currentPage && isPageStateEqual(currentPage, newPage)) { return; }
diff --git a/chrome/browser/resources/md_extensions/runtime_hosts_dialog.js b/chrome/browser/resources/md_extensions/runtime_hosts_dialog.js index 32e0551..c534d70a 100644 --- a/chrome/browser/resources/md_extensions/runtime_hosts_dialog.js +++ b/chrome/browser/resources/md_extensions/runtime_hosts_dialog.js
@@ -29,12 +29,12 @@ '$'); function getPatternFromSite(site) { - let res = patternRegExp.exec(site); + const res = patternRegExp.exec(site); assert(res); - let scheme = res[1] || '*://'; - let host = (res[3] || '') + res[4]; - let port = res[5] || ''; - let path = '/*'; + const scheme = res[1] || '*://'; + const host = (res[3] || '') + res[4]; + const port = res[5] || ''; + const path = '/*'; return scheme + host + port + path; } @@ -109,7 +109,7 @@ return; } - let valid = patternRegExp.test(this.site_); + const valid = patternRegExp.test(this.site_); this.inputInvalid_ = !valid; }, @@ -204,7 +204,7 @@ * @private */ addPermission_: function() { - let pattern = getPatternFromSite(this.site_); + const pattern = getPatternFromSite(this.site_); this.delegate.addRuntimeHostPermission(this.itemId, pattern) .then( () => {
diff --git a/chrome/browser/resources/md_extensions/service.js b/chrome/browser/resources/md_extensions/service.js index 312a1e5..7503f87 100644 --- a/chrome/browser/resources/md_extensions/service.js +++ b/chrome/browser/resources/md_extensions/service.js
@@ -350,6 +350,51 @@ resolve); }); } + + /** @override */ + getFilteredExtensionActivityLog(extensionId, searchTerm) { + const anyType = chrome.activityLogPrivate.ExtensionActivityFilter.ANY; + + // Construct one filter for each API call we will make: one for exact + // match on the api call (api does not support partial matches), one for + // substring search by page URL, and one for substring search by argument + // URL. For the last two, % acts as a wildcard. + const activityLogFilters = [ + { + activityType: anyType, + extensionId: extensionId, + apiCall: `%${searchTerm}%`, + }, + { + activityType: anyType, + extensionId: extensionId, + pageUrl: `%${searchTerm}%`, + }, + { + activityType: anyType, + extensionId: extensionId, + argUrl: `%${searchTerm}%` + } + ]; + + const promises = activityLogFilters.map( + filter => new Promise(function(resolve, reject) { + chrome.activityLogPrivate.getExtensionActivities(filter, resolve); + })); + + return Promise.all(promises).then(results => { + // We may have results that are present in one or more searches, so + // we merge them here. We also assume that every distinct activity + // id corresponds to exactly one activity. + const activitiesById = new Map(); + for (const result of results) { + for (const activity of result.activities) + activitiesById.set(activity.activityId, activity); + } + + return {activities: Array.from(activitiesById.values())}; + }); + } } cr.addSingletonGetter(Service);
diff --git a/chrome/browser/resources/md_extensions/shortcut_input.js b/chrome/browser/resources/md_extensions/shortcut_input.js index cc822d13..affdc08 100644 --- a/chrome/browser/resources/md_extensions/shortcut_input.js +++ b/chrome/browser/resources/md_extensions/shortcut_input.js
@@ -199,7 +199,7 @@ * @private */ computeText_: function() { - let shortcutString = + const shortcutString = this.capturing_ ? this.pendingShortcut_ : this.shortcut; return shortcutString.split('+').join(' + '); },
diff --git a/chrome/browser/resources/md_extensions/shortcut_util.js b/chrome/browser/resources/md_extensions/shortcut_util.js index 75f235c..644c3e3 100644 --- a/chrome/browser/resources/md_extensions/shortcut_util.js +++ b/chrome/browser/resources/md_extensions/shortcut_util.js
@@ -76,7 +76,7 @@ function isValidKeyCode(keyCode) { if (keyCode == Key.Escape) return false; - for (let k in Key) { + for (const k in Key) { if (Key[k] == keyCode) return true; } @@ -91,7 +91,7 @@ * @return {string} The keystroke as a string. */ function keystrokeToString(e) { - let output = []; + const output = []; // TODO(devlin): Should this be i18n'd? if (cr.isMac && e.metaKey) output.push('Command'); @@ -104,7 +104,7 @@ if (e.shiftKey) output.push('Shift'); - let keyCode = e.keyCode; + const keyCode = e.keyCode; if (isValidKeyCode(keyCode)) { if ((keyCode >= 'A'.charCodeAt(0) && keyCode <= 'Z'.charCodeAt(0)) || (keyCode >= '0'.charCodeAt(0) && keyCode <= '9'.charCodeAt(0))) {
diff --git a/chrome/browser/resources/md_history/BUILD.gn b/chrome/browser/resources/md_history/BUILD.gn index 70fca5d..77a88c0 100644 --- a/chrome/browser/resources/md_history/BUILD.gn +++ b/chrome/browser/resources/md_history/BUILD.gn
@@ -28,7 +28,7 @@ excludes = [ "chrome://resources/html/util.html", - "chrome://history/constants.html", + "constants.html", ] deps = []
diff --git a/chrome/browser/resources/md_history/app.html b/chrome/browser/resources/md_history/app.html index 5421f76f..c096a61 100644 --- a/chrome/browser/resources/md_history/app.html +++ b/chrome/browser/resources/md_history/app.html
@@ -6,12 +6,12 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-media-query/iron-media-query.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-pages/iron-pages.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-scroll-target-behavior/iron-scroll-target-behavior.html"> -<link rel="import" href="chrome://history/history_list.html"> -<link rel="import" href="chrome://history/history_toolbar.html"> -<link rel="import" href="chrome://history/query_manager.html"> -<link rel="import" href="chrome://history/router.html"> -<link rel="import" href="chrome://history/shared_style.html"> -<link rel="import" href="chrome://history/side_bar.html"> +<link rel="import" href="history_list.html"> +<link rel="import" href="history_toolbar.html"> +<link rel="import" href="query_manager.html"> +<link rel="import" href="router.html"> +<link rel="import" href="shared_style.html"> +<link rel="import" href="side_bar.html"> <!-- Lazy loaded: history-synced-device-manager, cr-drawer. --> @@ -120,5 +120,5 @@ query-matches="{{hasDrawer_}}"> </iron-media-query> </template> - <script src="chrome://history/app.js"></script> + <script src="app.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_history/app.js b/chrome/browser/resources/md_history/app.js index eb8c2574..ee2a6be 100644 --- a/chrome/browser/resources/md_history/app.js +++ b/chrome/browser/resources/md_history/app.js
@@ -7,8 +7,7 @@ function ensureLazyLoaded() { if (!lazyLoadPromise) { lazyLoadPromise = new Promise(function(resolve, reject) { - Polymer.Base.importHref( - 'chrome://history/lazy_load.html', resolve, reject, true); + Polymer.Base.importHref('lazy_load.html', resolve, reject, true); }); } return lazyLoadPromise;
diff --git a/chrome/browser/resources/md_history/browser_service.html b/chrome/browser/resources/md_history/browser_service.html index 0c7e52f..6b330c1 100644 --- a/chrome/browser/resources/md_history/browser_service.html +++ b/chrome/browser/resources/md_history/browser_service.html
@@ -1,4 +1,4 @@ <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/promise_resolver.html"> -<link rel="import" href="chrome://history/constants.html"> -<script src="chrome://history/browser_service.js"></script> +<link rel="import" href="constants.html"> +<script src="browser_service.js"></script>
diff --git a/chrome/browser/resources/md_history/constants.html b/chrome/browser/resources/md_history/constants.html index 7d01ff31..2b6bc6b 100644 --- a/chrome/browser/resources/md_history/constants.html +++ b/chrome/browser/resources/md_history/constants.html
@@ -1 +1 @@ -<script src="chrome://history/constants.js"></script> +<script src="constants.js"></script>
diff --git a/chrome/browser/resources/md_history/history.html b/chrome/browser/resources/md_history/history.html index daa1ec1..a11ec825 100644 --- a/chrome/browser/resources/md_history/history.html +++ b/chrome/browser/resources/md_history/history.html
@@ -94,12 +94,12 @@ <link rel="import" href="chrome://resources/html/util.html"> <link rel="import" href="chrome://resources/html/load_time_data.html"> - <link rel="import" href="chrome://history/constants.html"> - <script src="chrome://history/strings.js"></script> - <script src="chrome://history/history.js"></script> + <link rel="import" href="constants.html"> + <script src="strings.js"></script> + <script src="history.js"></script> <link rel="import" href="chrome://resources/html/dark_mode.html"> - <link rel="import" href="chrome://history/app.html" async id="bundle"> + <link rel="import" href="app.html" async id="bundle"> </body> </html>
diff --git a/chrome/browser/resources/md_history/history_item.html b/chrome/browser/resources/md_history/history_item.html index 03903e2..9db1c4e 100644 --- a/chrome/browser/resources/md_history/history_item.html +++ b/chrome/browser/resources/md_history/history_item.html
@@ -1,9 +1,9 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://history/browser_service.html"> -<link rel="import" href="chrome://history/constants.html"> -<link rel="import" href="chrome://history/searched_label.html"> -<link rel="import" href="chrome://history/shared_style.html"> +<link rel="import" href="browser_service.html"> +<link rel="import" href="constants.html"> +<link rel="import" href="searched_label.html"> +<link rel="import" href="shared_style.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> @@ -224,5 +224,5 @@ <div id="time-gap-separator" hidden="[[!hasTimeGap]]"></div> </div> </template> - <script src="chrome://history/history_item.js"></script> + <script src="history_item.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_history/history_list.html b/chrome/browser/resources/md_history/history_list.html index 46cc926..e193467 100644 --- a/chrome/browser/resources/md_history/history_list.html +++ b/chrome/browser/resources/md_history/history_list.html
@@ -6,10 +6,10 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-announcer/iron-a11y-announcer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-scroll-threshold/iron-scroll-threshold.html"> -<link rel="import" href="chrome://history/browser_service.html"> -<link rel="import" href="chrome://history/constants.html"> -<link rel="import" href="chrome://history/history_item.html"> -<link rel="import" href="chrome://history/shared_style.html"> +<link rel="import" href="browser_service.html"> +<link rel="import" href="constants.html"> +<link rel="import" href="history_item.html"> +<link rel="import" href="shared_style.html"> <!-- Lazy loaded: cr-dialog, cr-action-menu, paper-button. --> @@ -94,5 +94,5 @@ </template> </cr-lazy-render> </template> - <script src="chrome://history/history_list.js"></script> + <script src="history_list.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_history/history_toolbar.html b/chrome/browser/resources/md_history/history_toolbar.html index 99706b5..aa3e9fd 100644 --- a/chrome/browser/resources/md_history/history_toolbar.html +++ b/chrome/browser/resources/md_history/history_toolbar.html
@@ -2,9 +2,9 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toolbar/cr_toolbar.html"> -<link rel="import" href="chrome://history/browser_service.html"> -<link rel="import" href="chrome://history/icons.html"> -<link rel="import" href="chrome://history/shared_style.html"> +<link rel="import" href="browser_service.html"> +<link rel="import" href="icons.html"> +<link rel="import" href="shared_style.html"> <!-- Lazy loaded: cr-toolbar-selection-overlay. --> @@ -60,5 +60,5 @@ on-delete-selected-items="deleteSelectedItems"> </cr-toolbar-selection-overlay> </template> - <script src="chrome://history/history_toolbar.js"></script> + <script src="history_toolbar.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_history/lazy_load.html b/chrome/browser/resources/md_history/lazy_load.html index 3298b3a..81a6d85e 100644 --- a/chrome/browser/resources/md_history/lazy_load.html +++ b/chrome/browser/resources/md_history/lazy_load.html
@@ -1,7 +1,7 @@ <html> <head></head> <body> - <link rel="import" href="chrome://history/synced_device_manager.html"> + <link rel="import" href="synced_device_manager.html"> <link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html"> <link rel="import" href="chrome://resources/cr_elements/cr_checkbox/cr_checkbox.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
diff --git a/chrome/browser/resources/md_history/router.html b/chrome/browser/resources/md_history/router.html index 7962fbce..d53cc98 100644 --- a/chrome/browser/resources/md_history/router.html +++ b/chrome/browser/resources/md_history/router.html
@@ -8,5 +8,5 @@ <iron-query-params params-string="{{query_}}" params-object="{{queryParams_}}"></iron-query-params> </template> - <script src="chrome://history/router.js"></script> + <script src="router.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_history/searched_label.html b/chrome/browser/resources/md_history/searched_label.html index 26f571d..a91da5c5 100644 --- a/chrome/browser/resources/md_history/searched_label.html +++ b/chrome/browser/resources/md_history/searched_label.html
@@ -2,5 +2,5 @@ <link rel="import" href="chrome://resources/html/util.html"> <dom-module id="history-searched-label"> - <script src="chrome://history/searched_label.js"></script> + <script src="searched_label.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_history/shared_style.html b/chrome/browser/resources/md_history/shared_style.html index 9fd5c3c..424a5e1 100644 --- a/chrome/browser/resources/md_history/shared_style.html +++ b/chrome/browser/resources/md_history/shared_style.html
@@ -1,4 +1,4 @@ -<link rel="import" href="chrome://history/shared_vars.html"> +<link rel="import" href="shared_vars.html"> <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
diff --git a/chrome/browser/resources/md_history/side_bar.html b/chrome/browser/resources/md_history/side_bar.html index c2fbbb2..791d35d89 100644 --- a/chrome/browser/resources/md_history/side_bar.html +++ b/chrome/browser/resources/md_history/side_bar.html
@@ -6,8 +6,8 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-ripple/paper-ripple.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/typography.html"> -<link rel="import" href="chrome://history/browser_service.html"> -<link rel="import" href="chrome://history/shared_style.html"> +<link rel="import" href="browser_service.html"> +<link rel="import" href="shared_style.html"> <dom-module id="history-side-bar"> <template> @@ -118,5 +118,5 @@ </div> </iron-selector> </template> - <script src="chrome://history/side_bar.js"></script> + <script src="side_bar.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_history/synced_device_card.html b/chrome/browser/resources/md_history/synced_device_card.html index c4387fc93..7518b3e 100644 --- a/chrome/browser/resources/md_history/synced_device_card.html +++ b/chrome/browser/resources/md_history/synced_device_card.html
@@ -7,10 +7,10 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="chrome://resources/html/icon.html"> -<link rel="import" href="chrome://history/browser_service.html"> -<link rel="import" href="chrome://history/constants.html"> -<link rel="import" href="chrome://history/searched_label.html"> -<link rel="import" href="chrome://history/shared_style.html"> +<link rel="import" href="browser_service.html"> +<link rel="import" href="constants.html"> +<link rel="import" href="searched_label.html"> +<link rel="import" href="shared_style.html"> <dom-module id="history-synced-device-card"> <template> @@ -124,5 +124,5 @@ </iron-collapse> </div> </template> - <script src="chrome://history/synced_device_card.js"></script> + <script src="synced_device_card.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_history/synced_device_manager.html b/chrome/browser/resources/md_history/synced_device_manager.html index c9eba5a3..12fb2ae9 100644 --- a/chrome/browser/resources/md_history/synced_device_manager.html +++ b/chrome/browser/resources/md_history/synced_device_manager.html
@@ -8,8 +8,8 @@ <link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> -<link rel="import" href="chrome://history/shared_style.html"> -<link rel="import" href="chrome://history/synced_device_card.html"> +<link rel="import" href="shared_style.html"> +<link rel="import" href="synced_device_card.html"> <dom-module id="history-synced-device-manager"> <template> @@ -21,8 +21,8 @@ #illustration { background: -webkit-image-set( - url(chrome://history/images/100/sign_in_promo.jpg) 1x, - url(chrome://history/images/200/sign_in_promo.jpg) 2x) + url(images/100/sign_in_promo.jpg) 1x, + url(images/200/sign_in_promo.jpg) 2x) no-repeat center center; height: 222px; margin-top: 100px; @@ -104,5 +104,5 @@ </template> </cr-lazy-render> </template> - <script src="chrome://history/synced_device_manager.js"></script> + <script src="synced_device_manager.js"></script> </dom-module>
diff --git a/chrome/browser/resources/memory_internals.js b/chrome/browser/resources/memory_internals.js index 023d13f..d6d0302 100644 --- a/chrome/browser/resources/memory_internals.js +++ b/chrome/browser/resources/memory_internals.js
@@ -23,9 +23,9 @@ // celltype should either be "td" or "th". The contents of the |cols| will be // added as children of each table cell if they are non-null. function addListRow(table, celltype, cols) { - let tr = document.createElement('tr'); - for (let col of cols) { - let cell = document.createElement(celltype); + const tr = document.createElement('tr'); + for (const col of cols) { + const cell = document.createElement(celltype); if (col) cell.appendChild(col); tr.appendChild(cell); @@ -40,32 +40,32 @@ function returnProcessList(data) { $('message').innerText = data['message']; - let proclist = $('proclist'); + const proclist = $('proclist'); proclist.innerText = ''; // Clear existing contents. - let processes = data['processes']; + const processes = data['processes']; if (processes.length == 0) return; // No processes to dump, don't make the table and refresh button. // Add the refresh and save-dump buttons. - let commandsDiv = document.createElement('div'); + const commandsDiv = document.createElement('div'); commandsDiv.className = 'commands'; - let refreshButton = document.createElement('button'); + const refreshButton = document.createElement('button'); refreshButton.innerText = '\u21ba Refresh process list'; refreshButton.onclick = () => requestProcessList(); commandsDiv.appendChild(refreshButton); - let saveDumpButton = document.createElement('button'); + const saveDumpButton = document.createElement('button'); saveDumpButton.innerText = '\u21e9 Save dump'; saveDumpButton.onclick = () => saveDump(); commandsDiv.appendChild(saveDumpButton); - let saveDumpText = document.createElement('div'); + const saveDumpText = document.createElement('div'); saveDumpText.id = 'save_dump_text'; commandsDiv.appendChild(saveDumpText); proclist.appendChild(commandsDiv); - let table = document.createElement('table'); + const table = document.createElement('table'); // Heading. addListRow(table, 'th', [
diff --git a/chrome/browser/resources/omnibox/omnibox.css b/chrome/browser/resources/omnibox/omnibox.css index acd4930..c84fbc9 100644 --- a/chrome/browser/resources/omnibox/omnibox.css +++ b/chrome/browser/resources/omnibox/omnibox.css
@@ -97,11 +97,14 @@ padding: 0 5px; } +th { + padding-bottom: 6px; + padding-top: 12px; +} + .header-container { display: block; overflow: hidden; - padding-bottom: 6px; - padding-top: 12px; text-overflow: ellipsis; white-space: nowrap; }
diff --git a/chrome/browser/resources/omnibox/omnibox.js b/chrome/browser/resources/omnibox/omnibox.js index 186c70ed..a878a2be 100644 --- a/chrome/browser/resources/omnibox/omnibox.js +++ b/chrome/browser/resources/omnibox/omnibox.js
@@ -65,11 +65,12 @@ omniboxInputs.addEventListener( 'display-inputs-changed', event => omniboxOutput.updateDisplayInputs(event.detail)); + omniboxInputs.addEventListener( + 'filter-input-changed', + event => omniboxOutput.updateFilterText(event.detail)); omniboxInputs.addEventListener('copy-request', event => { event.detail === 'text' ? omniboxOutput.copyDelegate.copyTextOutput() : omniboxOutput.copyDelegate.copyJsonOutput(); }); - omniboxInputs.addEventListener( - 'filter-input-changed', event => omniboxOutput.filter(event.detail)); }); })();
diff --git a/chrome/browser/resources/omnibox/omnibox_output.js b/chrome/browser/resources/omnibox/omnibox_output.js index 7809bea..d3dffa3 100644 --- a/chrome/browser/resources/omnibox/omnibox_output.js +++ b/chrome/browser/resources/omnibox/omnibox_output.js
@@ -24,6 +24,8 @@ this.queryInputs_ = /** @type {!QueryInputs} */ ({}); /** @private {!DisplayInputs} */ this.displayInputs_ = /** @type {!DisplayInputs} */ ({}); + /** @private {string} */ + this.filterText_ = ''; } /** @param {!QueryInputs} queryInputs */ @@ -37,6 +39,12 @@ this.updateVisibility_(); } + /** @param {string} filterText */ + updateFilterText(filterText) { + this.filterText_ = filterText; + this.updateFilterHighlights_(); + } + clearAutocompleteResponses() { this.responses = []; this.resultsGroups_ = []; @@ -53,6 +61,7 @@ this.$$('contents').appendChild(resultsGroup); this.updateVisibility_(); + this.updateFilterHighlights_(); } /** @@ -79,9 +88,9 @@ }); } - /** @param {string} filterText */ - filter(filterText) { - this.matches.forEach(match => match.filter(filterText)); + /** @private */ + updateFilterHighlights_() { + this.matches.forEach(match => match.filter(this.filterText_)); } /** @return {!Array<!OutputMatch>} */
diff --git a/chrome/browser/resources/policy_base.js b/chrome/browser/resources/policy_base.js index 202305b..de2122e 100644 --- a/chrome/browser/resources/policy_base.js +++ b/chrome/browser/resources/policy_base.js
@@ -315,7 +315,7 @@ // First, add known policies whose value is currently set. const unset = []; - for (let name in this.policies_) { + for (const name in this.policies_) { if (name in values) this.setPolicyValue_(name, values[name], false); else @@ -324,7 +324,7 @@ // Second, add policies whose value is currently set but whose name is not // recognized. - for (let name in values) { + for (const name in values) { if (!(name in this.policies_)) this.setPolicyValue_(name, values[name], true); }
diff --git a/chrome/browser/resources/print_preview/data/destination.js b/chrome/browser/resources/print_preview/data/destination.js index 074a2bb..166b748 100644 --- a/chrome/browser/resources/print_preview/data/destination.js +++ b/chrome/browser/resources/print_preview/data/destination.js
@@ -718,7 +718,7 @@ */ get srcSet() { let srcSetIcon = ''; - let iconUrl = this.iconUrl; + const iconUrl = this.iconUrl; if (iconUrl == Destination.IconUrl_.LOCAL_1X) { srcSetIcon = Destination.IconUrl_.LOCAL_2X; } else if (iconUrl == Destination.IconUrl_.CLOUD_1X) {
diff --git a/chrome/browser/resources/print_preview/new/advanced_settings_item.js b/chrome/browser/resources/print_preview/new/advanced_settings_item.js index b62d08e..9afa89b 100644 --- a/chrome/browser/resources/print_preview/new/advanced_settings_item.js +++ b/chrome/browser/resources/print_preview/new/advanced_settings_item.js
@@ -115,7 +115,7 @@ if (!this.isCapabilityTypeSelect_()) return false; - for (let option of + for (const option of /** @type {!Array<!print_preview.VendorCapabilitySelectOption>} */ ( this.capability.select_cap.option)) { if (this.getDisplayName_(option).match(query))
diff --git a/chrome/browser/resources/print_preview/new/margin_control_container.js b/chrome/browser/resources/print_preview/new/margin_control_container.js index 15b9310a..f7e31e0 100644 --- a/chrome/browser/resources/print_preview/new/margin_control_container.js +++ b/chrome/browser/resources/print_preview/new/margin_control_container.js
@@ -148,7 +148,7 @@ // Set the custom margins values to the current document margins if the // custom margins were reset. const newMargins = {}; - for (let side of Object.values( + for (const side of Object.values( print_preview.ticket_items.CustomMarginsOrientation)) { const key = print_preview_new.MARGIN_KEY_MAP.get(side); newMargins[key] = this.documentMargins.get(side);
diff --git a/chrome/browser/resources/print_preview/new/pages_settings.js b/chrome/browser/resources/print_preview/new/pages_settings.js index aae366c..ea13abf 100644 --- a/chrome/browser/resources/print_preview/new/pages_settings.js +++ b/chrome/browser/resources/print_preview/new/pages_settings.js
@@ -182,7 +182,7 @@ const added = {}; const ranges = this.inputString_.split(/,|\u3001/); const maxPage = this.allPagesArray_.length; - for (let range of ranges) { + for (const range of ranges) { if (range == '') { this.errorState_ = PagesInputErrorState.INVALID_SYNTAX; this.onRangeChange_(); @@ -253,7 +253,6 @@ * @private */ computeRangesToPrint_: function() { - let lastPage = 0; if (this.pagesToPrint_.length == 0 || this.pagesToPrint_[0] == -1 || this.pagesToPrint_ == this.allPagesArray_) { return []; @@ -261,8 +260,8 @@ let from = this.pagesToPrint_[0]; let to = this.pagesToPrint_[0]; - let ranges = []; - for (let page of this.pagesToPrint_.slice(1)) { + const ranges = []; + for (const page of this.pagesToPrint_.slice(1)) { if (page == to + 1) { to = page; continue;
diff --git a/chrome/browser/resources/print_preview/new/preview_area.js b/chrome/browser/resources/print_preview/new/preview_area.js index 082e2d4..1398d2c0 100644 --- a/chrome/browser/resources/print_preview/new/preview_area.js +++ b/chrome/browser/resources/print_preview/new/preview_area.js
@@ -585,7 +585,7 @@ /** @type {!print_preview.MarginsSetting} */ ( this.getSettingValue('customMargins')); - for (let side of Object.values( + for (const side of Object.values( print_preview.ticket_items.CustomMarginsOrientation)) { const key = print_preview_new.MARGIN_KEY_MAP.get(side); // If custom margins are undefined, return and wait for them to be set.
diff --git a/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js b/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js index 1a9ddd2..db8be8b 100644 --- a/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js +++ b/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js
@@ -229,7 +229,7 @@ * @private */ toggleStartupSoundEnabled_: function(e) { - let checked = /** @type {boolean} */ (e.detail); + const checked = /** @type {boolean} */ (e.detail); chrome.send('setStartupSoundEnabled', [checked]); },
diff --git a/chrome/browser/resources/settings/a11y_page/tts_subpage.js b/chrome/browser/resources/settings/a11y_page/tts_subpage.js index 465a831d..69574cf 100644 --- a/chrome/browser/resources/settings/a11y_page/tts_subpage.js +++ b/chrome/browser/resources/settings/a11y_page/tts_subpage.js
@@ -131,10 +131,11 @@ * @private */ initTick_: function(tick) { - let value = Math.round(100 * tick); - let strValue = value.toFixed(0); - let label = strValue === '100' ? this.i18n('defaultPercentage', strValue) : - this.i18n('percentage', strValue); + const value = Math.round(100 * tick); + const strValue = value.toFixed(0); + const label = strValue === '100' ? + this.i18n('defaultPercentage', strValue) : + this.i18n('percentage', strValue); return {label: label, value: tick, ariaValue: value}; }, @@ -166,10 +167,10 @@ */ populateVoiceList_: function(voices) { // Build a map of language code to human-readable language and voice. - let result = {}; - let languageCodeMap = {}; - let pref = this.prefs.settings['language']['preferred_languages']; - let preferredLangs = pref.value.split(','); + const result = {}; + const languageCodeMap = {}; + const pref = this.prefs.settings['language']['preferred_languages']; + const preferredLangs = pref.value.split(','); voices.forEach(voice => { if (!result[voice.languageCode]) { result[voice.languageCode] = { @@ -283,13 +284,13 @@ updateLangToVoicePrefs_: function(langToVoices) { if (langToVoices.length == 0) return; - let allCodes = new Set( + const allCodes = new Set( Object.keys(this.prefs.settings['tts']['lang_to_voice_name'].value)); - for (let code in langToVoices) { + for (const code in langToVoices) { // Remove from allCodes, to track what we've found a default for. allCodes.delete(code); - let voices = langToVoices[code].voices; - let defaultVoiceForLang = + const voices = langToVoices[code].voices; + const defaultVoiceForLang = this.prefs.settings['tts']['lang_to_voice_name'].value[code]; if (!defaultVoiceForLang || defaultVoiceForLang === '') { // Initialize prefs that have no value @@ -310,7 +311,7 @@ // If there are any items left in allCodes, they are for languages that are // no longer covered by the UI. We could now delete them from the // lang_to_voice_name pref. - for (let code of allCodes) { + for (const code of allCodes) { this.set('prefs.settings.tts.lang_to_voice_name.value.' + code, ''); } }, @@ -336,12 +337,12 @@ if (!this.defaultPreviewVoice) this.set('defaultPreviewVoice', this.getBestVoiceForLocale_(allVoices)); - let browserProxy = settings.LanguagesBrowserProxyImpl.getInstance(); + const browserProxy = settings.LanguagesBrowserProxyImpl.getInstance(); browserProxy.getProspectiveUILanguage().then(prospectiveUILanguage => { let result; if (prospectiveUILanguage && prospectiveUILanguage != '' && languageCodeMap[prospectiveUILanguage]) { - let code = languageCodeMap[prospectiveUILanguage]; + const code = languageCodeMap[prospectiveUILanguage]; // First try the pref value. result = this.prefs.settings['tts']['lang_to_voice_name'].value[code]; } @@ -386,9 +387,9 @@ // Log the default voice the user selected. Each voice has at most one // language, so there's no need to log language as well. // The event target is the settings-dropdown-menu. - let target = /** @type {{prefStringValue_: function():string}} */ + const target = /** @type {{prefStringValue_: function():string}} */ (event.target); - let newDefault = target.prefStringValue_(); + const newDefault = target.prefStringValue_(); chrome.metricsPrivate.recordSparseHashable( 'TextToSpeech.Settings.DefaultVoicePicked', newDefault); },
diff --git a/chrome/browser/resources/settings/about_page/about_page.html b/chrome/browser/resources/settings/about_page/about_page.html index 72c5f7e..5184ab7 100644 --- a/chrome/browser/resources/settings/about_page/about_page.html +++ b/chrome/browser/resources/settings/about_page/about_page.html
@@ -11,10 +11,8 @@ <link rel="import" href="../settings_page/settings_section.html"> <link rel="import" href="../settings_page_css.html"> <link rel="import" href="../settings_shared_css.html"> -<link rel="import" href="../settings_vars_css.html"> <link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html"> <link rel="import" href="chrome://resources/cr_elements/icons.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/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> @@ -39,25 +37,6 @@ --about-page-image-space: 10px; } - settings-section[section='about'] { - --settings-section-header: { - display: none; - }; - } - - h1 { - color: var(--cr-primary-text-color); - font-size: 108%; - font-weight: 400; - letter-spacing: .25px; - margin-bottom: 12px; - margin-inline-end: 3px; - margin-inline-start: 3px; - margin-top: var(--settings-page-vertical-margin); - padding-bottom: 4px; - padding-top: 8px; - } - .info-section { margin-bottom: 12px; } @@ -69,6 +48,7 @@ .product-title { font-size: 153.85%; /* 20px / 13px */ + font-weight: 400; margin-bottom: auto; margin-top: auto; } @@ -108,7 +88,6 @@ } </if> </style> - <h1>$i18n{aboutPageTitle}</h1> <div> <settings-section page-title="$i18n{aboutPageTitle}" section="about"> <settings-animated-pages id="pages" section="about" @@ -119,7 +98,7 @@ srcset="chrome://theme/current-channel-logo@1x 1x, chrome://theme/current-channel-logo@2x 2x" alt="$i18n{aboutProductLogoAlt}"> - <span class="product-title">$i18n{aboutProductTitle}</span> + <h1 class="product-title">$i18n{aboutProductTitle}</h1> </div> <div class="settings-box two-line"> <!-- TODO(dpapad): Investigate why vulcanize does not handle well
diff --git a/chrome/browser/resources/settings/about_page/channel_switcher_dialog.js b/chrome/browser/resources/settings/about_page/channel_switcher_dialog.js index 09ec861..29336e76 100644 --- a/chrome/browser/resources/settings/about_page/channel_switcher_dialog.js +++ b/chrome/browser/resources/settings/about_page/channel_switcher_dialog.js
@@ -6,7 +6,7 @@ /** */ -let WarningMessage = { +const WarningMessage = { NONE: -1, ENTERPRISE_MANAGED: 0, POWERWASH: 1,
diff --git a/chrome/browser/resources/settings/autofill_page/payments_section.js b/chrome/browser/resources/settings/autofill_page/payments_section.js index 068da8f..6c12018 100644 --- a/chrome/browser/resources/settings/autofill_page/payments_section.js +++ b/chrome/browser/resources/settings/autofill_page/payments_section.js
@@ -474,7 +474,7 @@ if (!syncStatus.signedIn || !syncStatus.syncSystemEnabled) return false; - let numberOfMigratableCreditCard = + const numberOfMigratableCreditCard = creditCards.filter(card => card.metadata.isMigratable).length; // Check whether exist at least one local valid card for migration. if (numberOfMigratableCreditCard == 0)
diff --git a/chrome/browser/resources/settings/controls/settings_toggle_button.js b/chrome/browser/resources/settings/controls/settings_toggle_button.js index 320cacdd2..86912e1 100644 --- a/chrome/browser/resources/settings/controls/settings_toggle_button.js +++ b/chrome/browser/resources/settings/controls/settings_toggle_button.js
@@ -44,7 +44,7 @@ */ onAriaLabelSet_: function() { if (this.hasAttribute('aria-label')) { - let ariaLabel = this.ariaLabel; + const ariaLabel = this.ariaLabel; this.removeAttribute('aria-label'); this.ariaLabel = ariaLabel; }
diff --git a/chrome/browser/resources/settings/crostini_page/crostini_shared_paths.js b/chrome/browser/resources/settings/crostini_page/crostini_shared_paths.js index f80802b..cc04e9ec 100644 --- a/chrome/browser/resources/settings/crostini_page/crostini_shared_paths.js +++ b/chrome/browser/resources/settings/crostini_page/crostini_shared_paths.js
@@ -37,7 +37,7 @@ settings.CrostiniBrowserProxyImpl.getInstance() .getCrostiniSharedPathsDisplayText(paths) .then(text => { - let sharedPaths = []; + const sharedPaths = []; for (let i = 0; i < paths.length; i++) { sharedPaths.push({path: paths[i], pathDisplayText: text[i]}); }
diff --git a/chrome/browser/resources/settings/date_time_page/timezone_subpage.js b/chrome/browser/resources/settings/date_time_page/timezone_subpage.js index 9db5266..f77b53e 100644 --- a/chrome/browser/resources/settings/date_time_page/timezone_subpage.js +++ b/chrome/browser/resources/settings/date_time_page/timezone_subpage.js
@@ -26,7 +26,7 @@ * @private */ getTimeZoneResolveMethodsList_: function() { - let result = []; + const result = []; // Make sure current value is in the list, even if it is not // user-selectable. if (this.getPref('generated.resolve_timezone_by_geolocation_method_short')
diff --git a/chrome/browser/resources/settings/device_page/display.js b/chrome/browser/resources/settings/device_page/display.js index 51ddbb4e..c145cb5 100644 --- a/chrome/browser/resources/settings/device_page/display.js +++ b/chrome/browser/resources/settings/device_page/display.js
@@ -369,7 +369,7 @@ * @private */ getDisplayModeOptionList_: function(selectedDisplay) { - let optionList = []; + const optionList = []; for (let i = 0; i < selectedDisplay.modes.length; ++i) { const option = this.i18n( 'displayResolutionMenuItem', @@ -840,13 +840,13 @@ event.target.blur(); /** @type {!chrome.system.display.MirrorModeInfo} */ - let mirrorModeInfo = { + const mirrorModeInfo = { mode: this.isMirrored_(this.displays) ? chrome.system.display.MirrorMode.OFF : chrome.system.display.MirrorMode.NORMAL }; settings.display.systemDisplayApi.setMirrorMode(mirrorModeInfo, () => { - let error = chrome.runtime.lastError; + const error = chrome.runtime.lastError; if (error) console.error('setMirrorMode Error: ' + error.message); });
diff --git a/chrome/browser/resources/settings/incompatible_applications_page/incompatible_applications_page.js b/chrome/browser/resources/settings/incompatible_applications_page/incompatible_applications_page.js index 0fd63da..07f20e6 100644 --- a/chrome/browser/resources/settings/incompatible_applications_page/incompatible_applications_page.js +++ b/chrome/browser/resources/settings/incompatible_applications_page/incompatible_applications_page.js
@@ -105,7 +105,7 @@ */ onIncompatibleApplicationRemoved_: function(applicationName) { // Find the index of the element. - let index = this.applications_.findIndex(function(application) { + const index = this.applications_.findIndex(function(application) { return application.name == applicationName; });
diff --git a/chrome/browser/resources/settings/internet_page/internet_page.js b/chrome/browser/resources/settings/internet_page/internet_page.js index c58f4c8..2e6a9aa8 100644 --- a/chrome/browser/resources/settings/internet_page/internet_page.js +++ b/chrome/browser/resources/settings/internet_page/internet_page.js
@@ -261,7 +261,7 @@ // iron-list makes the correct timing to focus an item in the list // very complicated, and the item may not exist, so just focus the // entire list for now. - let subPage = this.$$('settings-internet-subpage'); + const subPage = this.$$('settings-internet-subpage'); if (subPage) element = subPage.$$('#networkList'); } else if (this.detailType_) { @@ -383,7 +383,7 @@ * @private */ onDeviceStatesChanged_: function(newValue, oldValue) { - let wifiDeviceState = this.getDeviceState_(CrOnc.Type.WI_FI, newValue); + const wifiDeviceState = this.getDeviceState_(CrOnc.Type.WI_FI, newValue); let managedNetworkAvailable = false; if (!!wifiDeviceState) managedNetworkAvailable = !!wifiDeviceState.ManagedNetworkAvailable;
diff --git a/chrome/browser/resources/settings/multidevice_page/multidevice_page.js b/chrome/browser/resources/settings/multidevice_page/multidevice_page.js index eb91f995..94ff5197 100644 --- a/chrome/browser/resources/settings/multidevice_page/multidevice_page.js +++ b/chrome/browser/resources/settings/multidevice_page/multidevice_page.js
@@ -284,8 +284,8 @@ * @private */ onFeatureToggleClicked_: function(event) { - let feature = event.detail.feature; - let enabled = event.detail.enabled; + const feature = event.detail.feature; + const enabled = event.detail.enabled; // Disabling any feature does not require authentication, and enable some // features does not require authentication.
diff --git a/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.js b/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.js index 68781a00..76d5ec229 100644 --- a/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.js +++ b/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.js
@@ -8,7 +8,7 @@ * Describe the current URL input error status. * @enum {number} */ -let UrlInputError = { +const UrlInputError = { NONE: 0, INVALID_URL: 1, TOO_LONG: 2,
diff --git a/chrome/browser/resources/settings/people_page/people_page.js b/chrome/browser/resources/settings/people_page/people_page.js index dd0be9d..c528692 100644 --- a/chrome/browser/resources/settings/people_page/people_page.js +++ b/chrome/browser/resources/settings/people_page/people_page.js
@@ -138,10 +138,11 @@ value: function() { const map = new Map(); if (settings.routes.SYNC) { - const syncId = loadTimeData.getBoolean('unifiedConsentEnabled') ? - '#sync-setup' : - '#sync-status'; - map.set(settings.routes.SYNC.path, `${syncId} .subpage-arrow button`); + map.set( + settings.routes.SYNC.path, + loadTimeData.getBoolean('unifiedConsentEnabled') ? + '#sync-setup' : + '#sync-status .subpage-arrow button'); } // <if expr="not chromeos"> if (settings.routes.MANAGE_PROFILE) {
diff --git a/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js b/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js index 488afe0..36f0961 100644 --- a/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js +++ b/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js
@@ -45,7 +45,7 @@ .then( this.onGetPrinterPpdManufacturerAndModel_.bind(this), this.onGetPrinterPpdManufacturerAndModelFailed_.bind(this)); - let basename = this.getBaseName(this.activePrinter.printerPPDPath); + const basename = this.getBaseName(this.activePrinter.printerPPDPath); if (basename) { this.existingUserPPDMessage_ = loadTimeData.getStringF('currentPpdMessage', basename);
diff --git a/chrome/browser/resources/settings/search_settings.js b/chrome/browser/resources/settings/search_settings.js index 0d068f7..3a34994 100644 --- a/chrome/browser/resources/settings/search_settings.js +++ b/chrome/browser/resources/settings/search_settings.js
@@ -59,8 +59,8 @@ */ function findAndHighlightMatches_(request, root) { let foundMatches = false; - let highlights = []; - let bubbles = []; + const highlights = []; + const bubbles = []; const domIfTag = Polymer.DomIf ? 'DOM-IF' : 'TEMPLATE'; @@ -100,7 +100,7 @@ if (request.regExp.test(textContent)) { foundMatches = true; - let bubble = revealParentSection_(node, request.rawQuery_); + const bubble = revealParentSection_(node, request.rawQuery_); if (bubble) bubbles.push(bubble); @@ -439,7 +439,7 @@ removeAllHighlightsAndBubbles() { cr.search_highlight_utils.removeHighlights(this.highlights_); - for (let bubble of this.bubbles_) + for (const bubble of this.bubbles_) bubble.remove(); this.highlights_ = []; this.bubbles_ = [];
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.js b/chrome/browser/resources/settings/settings_main/settings_main.js index 3cd6eb5..08d9d66 100644 --- a/chrome/browser/resources/settings/settings_main/settings_main.js +++ b/chrome/browser/resources/settings/settings_main/settings_main.js
@@ -127,10 +127,12 @@ const inAbout = settings.routes.ABOUT.contains(settings.getCurrentRoute()); this.showPages_ = {about: inAbout, settings: !inAbout}; - document.title = inAbout ? - loadTimeData.getStringF( - 'settingsAltPageTitle', loadTimeData.getString('aboutPageTitle')) : - loadTimeData.getString('settings'); + if (!newRoute.isSubpage()) { + document.title = inAbout ? loadTimeData.getStringF( + 'settingsAltPageTitle', + loadTimeData.getString('aboutPageTitle')) : + loadTimeData.getString('settings'); + } }, /** @private */
diff --git a/chrome/browser/resources/settings/settings_page/settings_section.html b/chrome/browser/resources/settings/settings_page/settings_section.html index a2cdddc9..2c5a4f4a 100644 --- a/chrome/browser/resources/settings/settings_page/settings_section.html +++ b/chrome/browser/resources/settings/settings_page/settings_section.html
@@ -18,7 +18,6 @@ #header { margin-bottom: 12px; - @apply --settings-section-header; } #header .title {
diff --git a/chrome/browser/resources/settings/settings_page/settings_section.js b/chrome/browser/resources/settings/settings_page/settings_section.js index dbd3635..cff47f10 100644 --- a/chrome/browser/resources/settings/settings_page/settings_section.js +++ b/chrome/browser/resources/settings/settings_page/settings_section.js
@@ -16,6 +16,7 @@ * </settings-section> */ +// eslint-disable-next-line prefer-const let SettingsSectionElement = Polymer({ is: 'settings-section',
diff --git a/chrome/browser/resources/settings/settings_page/settings_subpage.js b/chrome/browser/resources/settings/settings_page/settings_subpage.js index 07940a1..07b8a16a 100644 --- a/chrome/browser/resources/settings/settings_page/settings_subpage.js +++ b/chrome/browser/resources/settings/settings_page/settings_subpage.js
@@ -52,13 +52,10 @@ active_: { type: Boolean, value: false, + observer: 'onActiveChanged_', }, }, - observers: [ - 'onActiveChanged_(active_, searchLabel)', - ], - /** @private {boolean} */ lastActiveValue_: false, @@ -91,10 +88,18 @@ /** @private */ onActiveChanged_: function() { - if (!this.searchLabel || this.lastActiveValue_ == this.active_) + if (this.lastActiveValue_ == this.active_) return; this.lastActiveValue_ = this.active_; + if (this.active_ && this.pageTitle) { + document.title = + loadTimeData.getStringF('settingsAltPageTitle', this.pageTitle); + } + + if (!this.searchLabel) + return; + if (this.active_) this.becomeActiveFindShortcutListener(); else
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 83ef46f9..3e095c2 100644 --- a/chrome/browser/resources/settings/site_settings/site_settings_behavior.js +++ b/chrome/browser/resources/settings/site_settings/site_settings_behavior.js
@@ -161,7 +161,7 @@ */ getCategoryList: function() { if (this.contentTypes_.length == 0) { - for (let typeName in settings.ContentSettingsTypes) { + for (const typeName in settings.ContentSettingsTypes) { const contentType = settings.ContentSettingsTypes[typeName]; // <if expr="not chromeos"> if (contentType == settings.ContentSettingsTypes.PROTECTED_CONTENT)
diff --git a/chrome/browser/resources/snippets_internals/snippets_internals.js b/chrome/browser/resources/snippets_internals/snippets_internals.js index 9c0ed744..2725f84 100644 --- a/chrome/browser/resources/snippets_internals/snippets_internals.js +++ b/chrome/browser/resources/snippets_internals/snippets_internals.js
@@ -147,7 +147,7 @@ const links = document.getElementsByClassName(toggleClass); for (const link of links) { link.onclick = function(event) { - let id = event.currentTarget.getAttribute('hidden-id'); + const id = event.currentTarget.getAttribute('hidden-id'); $(id).classList.toggle('hidden'); }; }
diff --git a/chrome/browser/resources/usb_internals/usb_internals.js b/chrome/browser/resources/usb_internals/usb_internals.js index a09a7ea..a8b58b9 100644 --- a/chrome/browser/resources/usb_internals/usb_internals.js +++ b/chrome/browser/resources/usb_internals/usb_internals.js
@@ -13,15 +13,15 @@ function refreshDeviceList() { pageHandler.getTestDevices().then(function(response) { - let tableBody = $('test-device-list'); + const tableBody = $('test-device-list'); tableBody.innerHTML = ''; - for (let device of response.devices) { - let row = document.createElement('tr'); - let name = document.createElement('td'); - let serialNumber = document.createElement('td'); - let landingPage = document.createElement('td'); - let remove = document.createElement('td'); - let removeButton = document.createElement('button'); + for (const device of response.devices) { + const row = document.createElement('tr'); + const name = document.createElement('td'); + const serialNumber = document.createElement('td'); + const landingPage = document.createElement('td'); + const remove = document.createElement('td'); + const removeButton = document.createElement('button'); name.textContent = device.name; serialNumber.textContent = device.serialNumber; landingPage.textContent = device.landingPage.url;
diff --git a/chrome/browser/safe_browsing/download_protection/file_analyzer.cc b/chrome/browser/safe_browsing/download_protection/file_analyzer.cc index 56ec18ce..444fd075 100644 --- a/chrome/browser/safe_browsing/download_protection/file_analyzer.cc +++ b/chrome/browser/safe_browsing/download_protection/file_analyzer.cc
@@ -111,7 +111,7 @@ // archive-type extension, then calls ExtractFileOrDmgFeatures() with // result. base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, base::BindOnce(DiskImageTypeSnifferMac::IsAppleDiskImage, tmp_path_), base::BindOnce(&FileAnalyzer::ExtractFileOrDmgFeatures, weakptr_factory_.GetWeakPtr())); @@ -126,7 +126,7 @@ base::PostTaskWithTraitsAndReplyWithResult( FROM_HERE, - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + {base::MayBlock(), base::TaskPriority::USER_VISIBLE, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::BindOnce(&ExtractFileFeatures, binary_feature_extractor_, tmp_path_),
diff --git a/chrome/browser/signin/chromeos_mirror_account_consistency_browsertest.cc b/chrome/browser/signin/chromeos_mirror_account_consistency_browsertest.cc index 34c81b110..85fac49 100644 --- a/chrome/browser/signin/chromeos_mirror_account_consistency_browsertest.cc +++ b/chrome/browser/signin/chromeos_mirror_account_consistency_browsertest.cc
@@ -2,93 +2,61 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/task/post_task.h" #include "chrome/browser/chromeos/login/login_manager_test.h" #include "chrome/browser/chromeos/login/startup_utils.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/prefs/incognito_mode_prefs.h" #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" #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/pref_names.h" -#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" #include "components/account_id/account_id.h" +#include "components/google/core/common/google_util.h" +#include "components/network_session_configurator/common/network_switches.h" #include "components/prefs/pref_service.h" -#include "components/signin/core/browser/account_consistency_method.h" #include "components/signin/core/browser/signin_header_helper.h" #include "components/signin/core/browser/signin_pref_names.h" #include "components/user_manager/user.h" #include "components/user_manager/user_manager.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/resource_context.h" -#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "net/test/embedded_test_server/default_handlers.h" +#include "net/test/embedded_test_server/embedded_test_server.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" -#include "net/url_request/url_request.h" -#include "net/url_request/url_request_context.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" namespace { -constexpr char kGaiaUrl[] = "https://accounts.google.com"; -constexpr char kChromeConnectedHeader[] = "X-Chrome-Connected"; +constexpr char kGaiaDomain[] = "accounts.google.com"; constexpr char kUserEmail[] = "user@gmail.com"; constexpr char kUserGaiaId[] = "1234567890"; -void CheckRequestHeader(net::URLRequest* url_request, - const char* header_name, - const std::string& expected_header_value) { - bool expected_has_header = !expected_header_value.empty(); - std::string actual_header_value; - EXPECT_EQ(expected_has_header, url_request->extra_request_headers().GetHeader( - header_name, &actual_header_value)) - << header_name << ": " << actual_header_value; - if (expected_has_header) { - EXPECT_EQ(expected_header_value, actual_header_value); - } -} - -void TestMirrorRequestForProfileOnIOThread( - ProfileIOData* profile_io, - const std::string& expected_header_value) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - - ASSERT_TRUE(profile_io->GetMainRequestContext()); - std::unique_ptr<net::URLRequest> request = - profile_io->GetMainRequestContext()->CreateRequest( - GURL(kGaiaUrl), net::DEFAULT_PRIORITY, nullptr, - TRAFFIC_ANNOTATION_FOR_TESTS); - signin::ChromeRequestAdapter signin_request_adapter(request.get()); - signin::FixAccountConsistencyRequestHeader(&signin_request_adapter, GURL(), - profile_io); - - CheckRequestHeader(request.get(), kChromeConnectedHeader, - expected_header_value); -} - // Checks whether the "X-Chrome-Connected" header of a new request to Google // contains |expected_header_value|. -void TestMirrorRequestForProfile(Profile* profile, +void TestMirrorRequestForProfile(net::EmbeddedTestServer* test_server, + Profile* profile, const std::string& expected_header_value) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + GURL gaia_url(test_server->GetURL("/echoheader?X-Chrome-Connected")); + GURL::Replacements replace_host; + replace_host.SetHostStr(kGaiaDomain); + gaia_url = gaia_url.ReplaceComponents(replace_host); - ProfileIOData* profile_io = - ProfileIOData::FromResourceContext(profile->GetResourceContext()); + Browser* browser = new Browser(Browser::CreateParams(profile, true)); + ui_test_utils::NavigateToURLWithDisposition( + browser, gaia_url, WindowOpenDisposition::SINGLETON_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); - base::RunLoop run_loop; - base::PostTaskWithTraitsAndReply( - FROM_HERE, {content::BrowserThread::IO}, - base::BindOnce(TestMirrorRequestForProfileOnIOThread, profile_io, - expected_header_value), - run_loop.QuitClosure()); - run_loop.Run(); + std::string inner_text; + ASSERT_TRUE(content::ExecuteScriptAndExtractString( + browser->tab_strip_model()->GetActiveWebContents(), + "domAutomationController.send(document.body.innerText);", &inner_text)); + // /echoheader returns "None" if the header isn't set. + inner_text = (inner_text == "None") ? "" : inner_text; + EXPECT_EQ(expected_header_value, inner_text); } } // namespace @@ -103,8 +71,34 @@ : LoginManagerTest(false, true /* should_initialize_webui */), account_id_(AccountId::FromUserEmailGaiaId(kUserEmail, kUserGaiaId)) {} + void SetUpCommandLine(base::CommandLine* command_line) override { + chromeos::LoginManagerTest::SetUpCommandLine(command_line); + + // HTTPS server only serves a valid cert for localhost, so this is needed to + // load pages from "www.google.com" without an interstitial. + command_line->AppendSwitch(switches::kIgnoreCertificateErrors); + } + + void SetUpOnMainThread() override { + // The production code only allows known ports (80 for http and 443 for + // https), but the test server runs on a random port. + google_util::IgnorePortNumbersForGoogleURLChecksForTesting(); + + // We can't use BrowserTestBase's EmbeddedTestServer because google.com + // URL's have to be https. + test_server_ = std::make_unique<net::EmbeddedTestServer>( + net::EmbeddedTestServer::TYPE_HTTPS); + net::test_server::RegisterDefaultHandlers(test_server_.get()); + ASSERT_TRUE(test_server_->Start()); + + chromeos::LoginManagerTest::SetUpOnMainThread(); + } + const AccountId account_id_; + protected: + std::unique_ptr<net::EmbeddedTestServer> test_server_; + private: DISALLOW_COPY_AND_ASSIGN(ChromeOsMirrorAccountConsistencyTest); }; @@ -146,7 +140,7 @@ ASSERT_EQ(3, signin::PROFILE_MODE_INCOGNITO_DISABLED | signin::PROFILE_MODE_ADD_ACCOUNT_DISABLED); - TestMirrorRequestForProfile(profile, + TestMirrorRequestForProfile(test_server_.get(), profile, "mode=3,enable_account_consistency=true"); } @@ -174,5 +168,5 @@ PrefService* prefs = profile->GetPrefs(); ASSERT_FALSE(prefs->GetBoolean(prefs::kAccountConsistencyMirrorRequired)); - TestMirrorRequestForProfile(profile, ""); + TestMirrorRequestForProfile(test_server_.get(), profile, ""); }
diff --git a/chrome/browser/signin/dice_browsertest.cc b/chrome/browser/signin/dice_browsertest.cc index 61681f4..c7f5f714 100644 --- a/chrome/browser/signin/dice_browsertest.cc +++ b/chrome/browser/signin/dice_browsertest.cc
@@ -34,10 +34,7 @@ #include "chrome/browser/signin/chrome_signin_client_factory.h" #include "chrome/browser/signin/chrome_signin_helper.h" #include "chrome/browser/signin/identity_manager_factory.h" -#include "chrome/browser/signin/mutable_profile_oauth2_token_service_delegate.h" -#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/scoped_account_consistency.h" -#include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/signin/signin_util.h" #include "chrome/browser/sync/user_event_service_factory.h" #include "chrome/browser/ui/browser.h" @@ -56,10 +53,8 @@ #include "components/signin/core/browser/account_reconcilor.h" #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/dice_header_helper.h" -#include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_client.h" #include "components/signin/core/browser/signin_header_helper.h" -#include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/browser/signin_metrics.h" #include "components/signin/core/browser/signin_pref_names.h" #include "components/sync/base/sync_prefs.h" @@ -72,12 +67,13 @@ #include "content/public/test/browser_test.h" #include "google_apis/gaia/gaia_switches.h" #include "google_apis/gaia/gaia_urls.h" -#include "google_apis/gaia/oauth2_token_service.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" #include "net/test/embedded_test_server/request_handler_util.h" #include "services/identity/public/cpp/identity_manager.h" +#include "services/identity/public/cpp/identity_test_utils.h" +#include "services/identity/public/cpp/primary_account_mutator.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -112,7 +108,6 @@ const char kOAuth2TokenExchangeURL[] = "/oauth2/v4/token"; const char kOAuth2TokenRevokeURL[] = "/o/oauth2/revoke"; const char kSecondaryEmail[] = "secondary_email@example.com"; -const char kSecondaryGaiaID[] = "secondary_gaia_id"; const char kSigninURL[] = "/signin"; const char kSignoutURL[] = "/signout"; @@ -233,9 +228,11 @@ if (signout_type == kAllAccounts || signout_type == kSecondaryAccount) { if (!signout_header_value.empty()) signout_header_value += ", "; + std::string secondary_gaia_id = + identity::GetTestGaiaIdForEmail(kSecondaryEmail); signout_header_value += base::StringPrintf("email=\"%s\", obfuscatedid=\"%s\", sessionindex=2", - kSecondaryEmail, kSecondaryGaiaID); + kSecondaryEmail, secondary_gaia_id.c_str()); } std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); @@ -365,12 +362,6 @@ ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(path)); } - // Returns the token service. - ProfileOAuth2TokenService* GetTokenService() { - return ProfileOAuth2TokenServiceFactory::GetForProfile( - browser()->profile()); - } - // Returns the account tracker service. AccountTrackerService* GetAccountTrackerService() { return AccountTrackerServiceFactory::GetForProfile(browser()->profile()); @@ -381,21 +372,17 @@ return IdentityManagerFactory::GetForProfile(browser()->profile()); } - // Returns the signin manager. - SigninManager* GetSigninManager() { - return SigninManagerFactory::GetForProfile(browser()->profile()); - } - // Returns the account ID associated with |main_email_|, kMainGaiaID. std::string GetMainAccountID() { return GetAccountTrackerService()->PickAccountIdForAccount(kMainGaiaID, main_email_); } - // Returns the account ID associated with kSecondaryEmail, kSecondaryGaiaID. + // Returns the account ID associated with kSecondaryEmail and its associated + // gaia ID. std::string GetSecondaryAccountID() { - return GetAccountTrackerService()->PickAccountIdForAccount(kSecondaryGaiaID, - kSecondaryEmail); + return GetAccountTrackerService()->PickAccountIdForAccount( + identity::GetTestGaiaIdForEmail(kSecondaryEmail), kSecondaryEmail); } std::string GetDeviceId() { @@ -405,22 +392,26 @@ // Signin with a main account and add token for a secondary account. void SetupSignedInAccounts() { // Signin main account. - SigninManager* signin_manager = GetSigninManager(); - signin_manager->StartSignInWithRefreshToken( + auto* primary_account_mutator = + GetIdentityManager()->GetPrimaryAccountMutator(); + primary_account_mutator->LegacyStartSigninWithRefreshTokenForPrimaryAccount( "existing_refresh_token", kMainGaiaID, main_email_, "password", - SigninManager::OAuthTokenFetchedCallback()); - ASSERT_TRUE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); - ASSERT_FALSE(GetTokenService()->RefreshTokenHasError(GetMainAccountID())); - ASSERT_EQ(GetMainAccountID(), signin_manager->GetAuthenticatedAccountId()); + base::OnceCallback<void(const std::string&)>()); + ASSERT_TRUE( + GetIdentityManager()->HasAccountWithRefreshToken(GetMainAccountID())); + ASSERT_FALSE( + GetIdentityManager()->HasAccountWithRefreshTokenInPersistentErrorState( + GetMainAccountID())); + ASSERT_EQ(GetMainAccountID(), GetIdentityManager()->GetPrimaryAccountId()); // Add a token for a secondary account. - std::string secondary_account_id = - GetAccountTrackerService()->SeedAccountInfo(kSecondaryGaiaID, - kSecondaryEmail); - GetTokenService()->UpdateCredentials(secondary_account_id, "other_token"); - ASSERT_TRUE( - GetTokenService()->RefreshTokenIsAvailable(secondary_account_id)); - ASSERT_FALSE(GetTokenService()->RefreshTokenHasError(secondary_account_id)); + AccountInfo secondary_account_info = + identity::MakeAccountAvailable(GetIdentityManager(), kSecondaryEmail); + ASSERT_TRUE(GetIdentityManager()->HasAccountWithRefreshToken( + secondary_account_info.account_id)); + ASSERT_FALSE( + GetIdentityManager()->HasAccountWithRefreshTokenInPersistentErrorState( + secondary_account_info.account_id)); } // Navigate to a Gaia URL setting the Google-Accounts-SignOut header. @@ -460,9 +451,10 @@ GetIdentityManager()->AddObserver(this); // Wait for the token service to be ready. - if (!GetTokenService()->AreAllCredentialsLoaded()) + if (!identity::AreAllCredentialsLoaded(GetIdentityManager())) { WaitForClosure(&tokens_loaded_quit_closure_); - ASSERT_TRUE(GetTokenService()->AreAllCredentialsLoaded()); + } + ASSERT_TRUE(identity::AreAllCredentialsLoaded(GetIdentityManager())); AccountReconcilor* reconcilor = AccountReconcilorFactory::GetForProfile(browser()->profile()); @@ -669,10 +661,14 @@ // Check that the token was requested and added to the token service. SendRefreshTokenResponse(); - EXPECT_TRUE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); + EXPECT_TRUE( + GetIdentityManager()->HasAccountWithRefreshToken(GetMainAccountID())); // Sync should not be enabled. - EXPECT_TRUE(GetSigninManager()->GetAuthenticatedAccountId().empty()); - EXPECT_TRUE(GetSigninManager()->GetAccountIdForAuthInProgress().empty()); + EXPECT_TRUE(GetIdentityManager()->GetPrimaryAccountId().empty()); + EXPECT_TRUE(GetIdentityManager() + ->GetPrimaryAccountMutator() + ->LegacyPrimaryAccountForAuthInProgress() + .account_id.empty()); EXPECT_EQ(1, reconcilor_blocked_count_); WaitForReconcilorUnblockedCount(1); @@ -701,8 +697,7 @@ // Check that the token was requested and added to the token service. SendRefreshTokenResponse(); - EXPECT_EQ(GetMainAccountID(), - GetSigninManager()->GetAuthenticatedAccountId()); + EXPECT_EQ(GetMainAccountID(), GetIdentityManager()->GetPrimaryAccountId()); // Old token must not be revoked (see http://crbug.com/865189). EXPECT_EQ(0, token_revoked_notification_count_); @@ -721,19 +716,14 @@ SignOutWithDice(kMainAccount); // Check that the user is in error state. - EXPECT_EQ(GetMainAccountID(), - GetSigninManager()->GetAuthenticatedAccountId()); - MutableProfileOAuth2TokenServiceDelegate* delegate = - static_cast<MutableProfileOAuth2TokenServiceDelegate*>( - GetTokenService()->GetDelegate()); - EXPECT_TRUE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); - EXPECT_TRUE(GetTokenService()->RefreshTokenHasError(GetMainAccountID())); - EXPECT_EQ(MutableProfileOAuth2TokenServiceDelegate::kInvalidRefreshToken, - delegate->GetRefreshTokenForTest(GetMainAccountID())); + EXPECT_EQ(GetMainAccountID(), GetIdentityManager()->GetPrimaryAccountId()); EXPECT_TRUE( - GetTokenService()->RefreshTokenIsAvailable(GetSecondaryAccountID())); - EXPECT_EQ("other_token", - delegate->GetRefreshTokenForTest(GetSecondaryAccountID())); + GetIdentityManager()->HasAccountWithRefreshToken(GetMainAccountID())); + EXPECT_TRUE( + GetIdentityManager()->HasAccountWithRefreshTokenInPersistentErrorState( + GetMainAccountID())); + EXPECT_TRUE(GetIdentityManager()->HasAccountWithRefreshToken( + GetSecondaryAccountID())); // Token for main account is revoked on server but not notified in the client. EXPECT_EQ(0, token_revoked_notification_count_); @@ -754,11 +744,11 @@ // Check that the user is still signed in from main account, but secondary // token is deleted. - EXPECT_EQ(GetMainAccountID(), - GetSigninManager()->GetAuthenticatedAccountId()); - EXPECT_TRUE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); - EXPECT_FALSE( - GetTokenService()->RefreshTokenIsAvailable(GetSecondaryAccountID())); + EXPECT_EQ(GetMainAccountID(), GetIdentityManager()->GetPrimaryAccountId()); + EXPECT_TRUE( + GetIdentityManager()->HasAccountWithRefreshToken(GetMainAccountID())); + EXPECT_FALSE(GetIdentityManager()->HasAccountWithRefreshToken( + GetSecondaryAccountID())); EXPECT_EQ(1, token_revoked_notification_count_); WaitForTokenRevokedCount(1); EXPECT_EQ(1, reconcilor_blocked_count_); @@ -774,17 +764,14 @@ SignOutWithDice(kAllAccounts); // Check that the user is in error state. - EXPECT_EQ(GetMainAccountID(), - GetSigninManager()->GetAuthenticatedAccountId()); - EXPECT_TRUE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); - EXPECT_TRUE(GetTokenService()->RefreshTokenHasError(GetMainAccountID())); - MutableProfileOAuth2TokenServiceDelegate* delegate = - static_cast<MutableProfileOAuth2TokenServiceDelegate*>( - GetTokenService()->GetDelegate()); - EXPECT_EQ(MutableProfileOAuth2TokenServiceDelegate::kInvalidRefreshToken, - delegate->GetRefreshTokenForTest(GetMainAccountID())); - EXPECT_FALSE( - GetTokenService()->RefreshTokenIsAvailable(GetSecondaryAccountID())); + EXPECT_EQ(GetMainAccountID(), GetIdentityManager()->GetPrimaryAccountId()); + EXPECT_TRUE( + GetIdentityManager()->HasAccountWithRefreshToken(GetMainAccountID())); + EXPECT_TRUE( + GetIdentityManager()->HasAccountWithRefreshTokenInPersistentErrorState( + GetMainAccountID())); + EXPECT_FALSE(GetIdentityManager()->HasAccountWithRefreshToken( + GetSecondaryAccountID())); // Token for main account is revoked on server but not notified in the client. EXPECT_EQ(1, token_revoked_notification_count_); @@ -824,9 +811,11 @@ signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS); // Receive token. - EXPECT_FALSE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); + EXPECT_FALSE( + GetIdentityManager()->HasAccountWithRefreshToken(GetMainAccountID())); SendRefreshTokenResponse(); - EXPECT_TRUE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); + EXPECT_TRUE( + GetIdentityManager()->HasAccountWithRefreshToken(GetMainAccountID())); // Receive ENABLE_SYNC. SendEnableSyncResponse(); @@ -845,8 +834,7 @@ content::NotificationService::AllSources()); WaitForSigninSucceeded(); - EXPECT_EQ(GetMainAccountID(), - GetSigninManager()->GetAuthenticatedAccountId()); + EXPECT_EQ(GetMainAccountID(), GetIdentityManager()->GetPrimaryAccountId()); EXPECT_EQ(1, reconcilor_blocked_count_); WaitForReconcilorUnblockedCount(1); @@ -880,9 +868,11 @@ enable_sync_url_observer.Wait(); // Receive token. - EXPECT_FALSE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); + EXPECT_FALSE( + GetIdentityManager()->HasAccountWithRefreshToken(GetMainAccountID())); SendRefreshTokenResponse(); - EXPECT_TRUE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); + EXPECT_TRUE( + GetIdentityManager()->HasAccountWithRefreshToken(GetMainAccountID())); // Check that the Dice request header was sent, with signout confirmation. std::string client_id = GaiaUrls::GetInstance()->oauth2_chrome_client_id(); @@ -898,8 +888,7 @@ content::NotificationService::AllSources()); WaitForSigninSucceeded(); - EXPECT_EQ(GetMainAccountID(), - GetSigninManager()->GetAuthenticatedAccountId()); + EXPECT_EQ(GetMainAccountID(), GetIdentityManager()->GetPrimaryAccountId()); EXPECT_EQ(1, reconcilor_blocked_count_); WaitForReconcilorUnblockedCount(1); @@ -922,9 +911,13 @@ EXPECT_TRUE(AccountConsistencyModeManager::IsDiceEnabledForProfile( browser()->profile())); - EXPECT_FALSE(GetSigninManager()->GetAuthenticatedAccountId().empty()); - EXPECT_TRUE(GetSigninManager()->GetAccountIdForAuthInProgress().empty()); - EXPECT_TRUE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); + EXPECT_FALSE(GetIdentityManager()->GetPrimaryAccountId().empty()); + EXPECT_TRUE(GetIdentityManager() + ->GetPrimaryAccountMutator() + ->LegacyPrimaryAccountForAuthInProgress() + .account_id.empty()); + EXPECT_TRUE( + GetIdentityManager()->HasAccountWithRefreshToken(GetMainAccountID())); EXPECT_FALSE(GetAccountTrackerService()->GetAccounts().empty()); // Turn off Dice for this profile. @@ -941,9 +934,13 @@ EXPECT_FALSE(AccountConsistencyModeManager::IsDiceEnabledForProfile( browser()->profile())); - EXPECT_TRUE(GetSigninManager()->GetAuthenticatedAccountId().empty()); - EXPECT_TRUE(GetSigninManager()->GetAccountIdForAuthInProgress().empty()); - EXPECT_FALSE(GetTokenService()->RefreshTokenIsAvailable(GetMainAccountID())); + EXPECT_TRUE(GetIdentityManager()->GetPrimaryAccountId().empty()); + EXPECT_TRUE(GetIdentityManager() + ->GetPrimaryAccountMutator() + ->LegacyPrimaryAccountForAuthInProgress() + .account_id.empty()); + EXPECT_FALSE( + GetIdentityManager()->HasAccountWithRefreshToken(GetMainAccountID())); EXPECT_TRUE(GetAccountTrackerService()->GetAccounts().empty()); // Navigate to Gaia and sign in.
diff --git a/chrome/browser/signin/fake_signin_manager_builder.cc b/chrome/browser/signin/fake_signin_manager_builder.cc index 1f7ab7f..8fedf7e 100644 --- a/chrome/browser/signin/fake_signin_manager_builder.cc +++ b/chrome/browser/signin/fake_signin_manager_builder.cc
@@ -30,7 +30,6 @@ FakeSigninManagerForTesting::FakeSigninManagerForTesting(Profile* profile) : FakeSigninManagerBase( ChromeSigninClientFactory::GetForProfile(profile), - ProfileOAuth2TokenServiceFactory::GetForProfile(profile), AccountTrackerServiceFactory::GetForProfile(profile), SigninErrorControllerFactory::GetForProfile(profile)) {} #else
diff --git a/chrome/browser/signin/signin_manager_factory.cc b/chrome/browser/signin/signin_manager_factory.cc index 7e9ba743..710183b 100644 --- a/chrome/browser/signin/signin_manager_factory.cc +++ b/chrome/browser/signin/signin_manager_factory.cc
@@ -115,8 +115,7 @@ ChromeSigninClientFactory::GetInstance()->GetForProfile(profile); #if defined(OS_CHROMEOS) service = new SigninManagerBase( - client, ProfileOAuth2TokenServiceFactory::GetForProfile(profile), - AccountTrackerServiceFactory::GetForProfile(profile), + client, AccountTrackerServiceFactory::GetForProfile(profile), SigninErrorControllerFactory::GetForProfile(profile)); #else service = new SigninManager(
diff --git a/chrome/browser/signin/signin_promo_util.cc b/chrome/browser/signin/signin_promo_util.cc index ba55a8a..7013b71 100644 --- a/chrome/browser/signin/signin_promo_util.cc +++ b/chrome/browser/signin/signin_promo_util.cc
@@ -5,9 +5,12 @@ #include "chrome/browser/signin/signin_promo_util.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/signin_manager_factory.h" -#include "components/signin/core/browser/signin_manager.h" +#include "chrome/browser/signin/identity_manager_factory.h" +#include "components/prefs/pref_service.h" +#include "components/signin/core/browser/signin_pref_names.h" #include "net/base/network_change_notifier.h" +#include "services/identity/public/cpp/identity_manager.h" +#include "services/identity/public/cpp/primary_account_mutator.h" namespace signin { @@ -22,15 +25,29 @@ if (net::NetworkChangeNotifier::IsOffline()) return false; + // Consider original profile even if an off-the-record profile was + // passed to this method as sign-in state is only defined for the + // primary profile. + Profile* original_profile = profile->GetOriginalProfile(); + // Don't show for supervised profiles. - if (profile->IsSupervised()) + if (original_profile->IsSupervised()) + return false; + + // Don't show if sign-in is not allowed. + if (!original_profile->GetPrefs()->GetBoolean(prefs::kSigninAllowed)) return false; // Display the signin promo if the user is not signed in. - SigninManager* signin = - SigninManagerFactory::GetForProfile(profile->GetOriginalProfile()); - return !signin->AuthInProgress() && signin->IsSigninAllowed() && - !signin->IsAuthenticated(); + identity::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(original_profile); + if (identity_manager->HasPrimaryAccount() || + identity_manager->GetPrimaryAccountMutator() + ->LegacyIsPrimaryAccountAuthInProgress()) { + return false; + } + + return true; #endif }
diff --git a/chrome/browser/sync/test/integration/enable_disable_test.cc b/chrome/browser/sync/test/integration/enable_disable_test.cc index 636a5a4a..b46cff64 100644 --- a/chrome/browser/sync/test/integration/enable_disable_test.cc +++ b/chrome/browser/sync/test/integration/enable_disable_test.cc
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/run_loop.h" #include "base/test/bind_test_util.h" +#include "base/test/metrics/histogram_tester.h" #include "base/values.h" #include "chrome/browser/sync/test/integration/bookmarks_helper.h" #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" @@ -418,13 +419,20 @@ ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureActive()); // Now start full Sync again. + base::HistogramTester histogram_tester; GetClient(0)->StartSyncService(); ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureActive()); // The bookmark should still be there, *without* having been redownloaded. + ASSERT_TRUE(SetupSync()); ASSERT_TRUE(bookmarks_helper::GetBookmarkModel(0)->IsBookmarked( GURL(kSyncedBookmarkURL))); - EXPECT_EQ(0, GetNumUpdatesDownloadedInLastCycle()); + EXPECT_EQ( + 0, histogram_tester.GetBucketCount("Sync.ModelTypeEntityChange3.BOOKMARK", + /*REMOTE_NON_INITIAL_UPDATE=*/4)); + EXPECT_EQ( + 0, histogram_tester.GetBucketCount("Sync.ModelTypeEntityChange3.BOOKMARK", + /*REMOTE_INITIAL_UPDATE=*/5)); } } // namespace
diff --git a/chrome/browser/task_manager/providers/crostini/crostini_process_task_provider.cc b/chrome/browser/task_manager/providers/crostini/crostini_process_task_provider.cc index d693126..71dd8d9 100644 --- a/chrome/browser/task_manager/providers/crostini/crostini_process_task_provider.cc +++ b/chrome/browser/task_manager/providers/crostini/crostini_process_task_provider.cc
@@ -25,9 +25,8 @@ // This is the binary executed for a VM process. constexpr char kVmProcessName[] = "/usr/bin/crosvm"; -// This is the suffix on VM disk names, and the actual name before the suffix -// will be the base64 encoded name of the VM itself. -constexpr char kVmDiskNameExtension[] = ".qcow2"; +// All VM disk images are contained in a subdirectory of this path. +constexpr char kVmDiskRoot[] = "/home/root/"; // Delay between refreshing the list of VM processes. constexpr base::TimeDelta kRefreshProcessListDelay = @@ -46,20 +45,41 @@ return base::kNullProcessId; } +// Check for the possible suffixes on VM disk names. The actual name before +// the suffix will be the base64 encoded name of the VM itself. +bool HasValidVmDiskExtension(const std::string& filename) { + constexpr const char* valid_extensions[] = { + ".qcow2", + ".img", + }; + + for (auto* const ext : valid_extensions) { + if (base::EndsWith(filename, ext, base::CompareCase::SENSITIVE)) { + return true; + } + } + return false; +} + // The argument this is extracting from will look like this: // /home/root/53d63eda33c610d37b44cde8ed06854a05e9cc84/crosvm/dGVybWluYQ==.qcow2 // This is the path to a VM disk in the user-specific root directory that is not // exposed to the user in the Files app. The base for this is /home/root and // the cryptohome ID for the user is the next path element. Then we have the // service specific 'crosvm' directory which we put VM images in. VM images use -// base64 encoding of the VM name as the filename with a .qcow2 extension. +// base64 encoding of the VM name as the filename with a .qcow2/.img extension. void ExtractVmNameAndOwnerIdFromCmdLine(const std::vector<std::string>& cmdline, std::string* vm_name_out, std::string* owner_id_out) { // Find the arg with the disk file path on it. for (const auto arg : cmdline) { - if (!base::EndsWith(arg, kVmDiskNameExtension, - base::CompareCase::SENSITIVE)) { + // Skip paths that don't start with the correct prefix to filter out the + // rootfs .img file. + if (!base::StartsWith(arg, kVmDiskRoot, base::CompareCase::SENSITIVE)) { + continue; + } + + if (!HasValidVmDiskExtension(arg)) { continue; }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 15266a3..7c54b10a 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2179,6 +2179,8 @@ "webui/settings/chrome_cleanup_handler.cc", "webui/settings/chrome_cleanup_handler.h", "webui/settings_utils_win.cc", + "webui/version_handler_win.cc", + "webui/version_handler_win.h", "webui/welcome/welcome_win10_handler.cc", "webui/welcome/welcome_win10_handler.h", "webui/welcome/welcome_win10_ui.cc",
diff --git a/chrome/browser/ui/ash/assistant/assistant_setup.cc b/chrome/browser/ui/ash/assistant/assistant_setup.cc index ced3e15..27227ab 100644 --- a/chrome/browser/ui/ash/assistant/assistant_setup.cc +++ b/chrome/browser/ui/ash/assistant/assistant_setup.cc
@@ -94,11 +94,12 @@ } void AssistantSetup::StartAssistantOptInFlow( + ash::mojom::FlowType type, StartAssistantOptInFlowCallback callback) { if (chromeos::AssistantOptInDialog::IsActive()) return; - chromeos::AssistantOptInDialog::Show(std::move(callback)); + chromeos::AssistantOptInDialog::Show(type, std::move(callback)); } void AssistantSetup::OnStateChanged(ash::mojom::VoiceInteractionState state) {
diff --git a/chrome/browser/ui/ash/assistant/assistant_setup.h b/chrome/browser/ui/ash/assistant/assistant_setup.h index aa62e8a0..a19653a 100644 --- a/chrome/browser/ui/ash/assistant/assistant_setup.h +++ b/chrome/browser/ui/ash/assistant/assistant_setup.h
@@ -24,6 +24,7 @@ // ash::mojom::AssistantSetup: void StartAssistantOptInFlow( + ash::mojom::FlowType type, StartAssistantOptInFlowCallback callback) override; private:
diff --git a/chrome/browser/ui/ash/keyboard/keyboard_end_to_end_browsertest.cc b/chrome/browser/ui/ash/keyboard/keyboard_end_to_end_browsertest.cc index c7a592df..9178256 100644 --- a/chrome/browser/ui/ash/keyboard/keyboard_end_to_end_browsertest.cc +++ b/chrome/browser/ui/ash/keyboard/keyboard_end_to_end_browsertest.cc
@@ -16,7 +16,6 @@ #include "content/public/test/browser_test_utils.h" #include "ui/aura/test/mus/change_completion_waiter.h" #include "ui/aura/window_tree_host.h" -#include "ui/base/ui_base_features.h" #include "ui/display/display.h" #include "ui/display/screen.h" #include "ui/keyboard/public/keyboard_switches.h" @@ -227,11 +226,6 @@ IN_PROC_BROWSER_TEST_F(KeyboardEndToEndFormTest, ChangeInputModeToNoneHidesKeyboard) { - // TODO(crbug.com/631527): RemoteTextInputClient is not forwarding focus - // requests to show/hide the virtual keyboard. - if (features::IsSingleProcessMash()) - return; - ClickElementWithId(web_contents_, "username"); ASSERT_TRUE(WaitUntilShown()); @@ -293,11 +287,6 @@ IN_PROC_BROWSER_TEST_F( KeyboardEndToEndFocusTest, TriggerAsyncInputFocusFromUserGestureAfterBlurShowsKeyboard) { - // TODO(crbug.com/631527): RemoteTextInputClient is not forwarding focus - // requests to show/hide the virtual keyboard. - if (features::IsSingleProcessMash()) - return; - // If async focus occurs quickly after blur, then it should still invoke the // keyboard. ClickElementWithId(web_contents_, "text");
diff --git a/chrome/browser/ui/ash/media_client.cc b/chrome/browser/ui/ash/media_client.cc index db2788a..562f44e 100644 --- a/chrome/browser/ui/ash/media_client.cc +++ b/chrome/browser/ui/ash/media_client.cc
@@ -29,6 +29,7 @@ #include "extensions/browser/app_window/app_window.h" #include "extensions/browser/app_window/app_window_registry.h" #include "extensions/browser/process_manager.h" +#include "services/media_session/public/mojom/media_session.mojom.h" #include "services/service_manager/public/cpp/connector.h" using ash::mojom::MediaCaptureState; @@ -189,13 +190,19 @@ void MediaClient::ToggleMediaSessionPlayPause( content::MediaSession* media_session) { - if (!media_session->IsControllable()) - return; + media_session->GetMediaSessionInfo(base::BindOnce( + [](content::MediaSession* media_session, + media_session::mojom::MediaSessionInfoPtr session_info) { + if (!session_info->is_controllable) + return; - if (media_session->IsActuallyPaused()) - media_session->Resume(content::MediaSession::SuspendType::kUI); - else - media_session->Suspend(content::MediaSession::SuspendType::kUI); + if (session_info->playback_state == + media_session::mojom::MediaPlaybackState::kPlaying) + media_session->Suspend(content::MediaSession::SuspendType::kUI); + else + media_session->Resume(content::MediaSession::SuspendType::kUI); + }, + media_session)); } void MediaClient::HandleMediaPrevTrack() {
diff --git a/chrome/browser/ui/browser_finder_chromeos_unittest.cc b/chrome/browser/ui/browser_finder_chromeos_unittest.cc index 5fe2125..fb60bf8 100644 --- a/chrome/browser/ui/browser_finder_chromeos_unittest.cc +++ b/chrome/browser/ui/browser_finder_chromeos_unittest.cc
@@ -10,6 +10,7 @@ #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_client.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_client_impl.h" +#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_client_impl_test_helper.h" #include "chrome/test/base/browser_with_test_window_test.h" #include "chrome/test/base/test_browser_window_aura.h" #include "chrome/test/base/testing_profile_manager.h" @@ -98,7 +99,7 @@ // Create an incognito browser. Browser::CreateParams params(profile()->GetOffTheRecordProfile(), true); std::unique_ptr<Browser> incognito_browser( - chrome::CreateBrowserWithAuraTestWindowForParams(nullptr, ¶ms)); + chrome::CreateBrowserWithViewsTestWindowForParams(params)); // Incognito windows are excluded in GetBrowserCount() because kMatchAll // doesn't match original profile of the browser with the given profile. EXPECT_EQ(0u, chrome::GetBrowserCount(profile())); @@ -107,14 +108,11 @@ } TEST_F(BrowserFinderChromeOSTest, FindBrowserOwnedByAnotherProfile) { - // TODO(crbug.com/910241): fix for mash. - if (features::IsSingleProcessMash()) - return; set_browser(nullptr); Browser::CreateParams params(profile()->GetOriginalProfile(), true); std::unique_ptr<Browser> browser( - chrome::CreateBrowserWithAuraTestWindowForParams(nullptr, ¶ms)); + chrome::CreateBrowserWithViewsTestWindowForParams(params)); GetUserWindowManager()->SetWindowOwner(browser->window()->GetNativeWindow(), test_account_id1_); EXPECT_EQ(1u, chrome::GetBrowserCount(profile())); @@ -125,6 +123,9 @@ // be available for the current profile. GetUserWindowManager()->ShowWindowForUser( browser->window()->GetNativeWindow(), test_account_id2_); + // ShowWindowForUser() notifies chrome async. FlushBindings() to ensure all + // the changes happen. + MultiUserWindowManagerClientImplTestHelper::FlushBindings(); EXPECT_EQ(0u, chrome::GetBrowserCount(profile())); EXPECT_FALSE(chrome::FindAnyBrowser(profile(), true)); EXPECT_FALSE(chrome::FindAnyBrowser(profile(), false));
diff --git a/chrome/browser/ui/startup/bad_flags_prompt.cc b/chrome/browser/ui/startup/bad_flags_prompt.cc index 5bad29a..e333d942 100644 --- a/chrome/browser/ui/startup/bad_flags_prompt.cc +++ b/chrome/browser/ui/startup/bad_flags_prompt.cc
@@ -114,6 +114,11 @@ // such as writing user data to disk, cleaning caches, reporting metrics or // updating components won't be performed until shutdown. switches::kDisableBackgroundTasks, + + // The UI for Web Bluetooth scanning is not yet implemented. Without the + // UI websites can scan for bluetooth without user intervention. Show a + // warning until the UI is complete. + switches::kEnableWebBluetoothScanning, }; #endif // OS_ANDROID
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc index 61df716..0e0cb617 100644 --- a/chrome/browser/ui/toolbar/app_menu_model.cc +++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -811,6 +811,9 @@ AddItemWithStringId(IDC_EXIT, IDS_EXIT); } + // On Chrome OS, similar UI is displayed in the system tray menu, instead of + // this menu. +#if !defined(OS_CHROMEOS) if (chrome::ShouldDisplayManagedUi(browser_->profile())) { AddSeparator(ui::LOWER_SEPARATOR); const int kIconSize = 18; @@ -820,6 +823,7 @@ AddHighlightedItemWithStringIdAndIcon(IDC_MANAGED_UI_HELP, IDS_MANAGED_BY_ORG, icon); } +#endif // !defined(OS_CHROMEOS) uma_action_recorded_ = false; }
diff --git a/chrome/browser/ui/views/badge_service_delegate_impl.cc b/chrome/browser/ui/views/badge_service_delegate_impl.cc index 7a87a4c..b616e68 100644 --- a/chrome/browser/ui/views/badge_service_delegate_impl.cc +++ b/chrome/browser/ui/views/badge_service_delegate_impl.cc
@@ -4,11 +4,15 @@ #include "chrome/browser/badging/badge_service_delegate.h" +#include "base/i18n/number_formatting.h" +#include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "content/public/browser/web_contents.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/strings/grit/ui_strings.h" #if defined(OS_WIN) #include "chrome/browser/ui/views/frame/taskbar_decorator_win.cc" @@ -40,15 +44,30 @@ } #endif +#if defined(OS_WIN) || defined(OS_MACOSX) +std::string GetBadgeString(base::Optional<uint64_t> badge_content) { + if (!badge_content) + return "•"; + + if (badge_content > 99u) { + return base::UTF16ToUTF8(l10n_util::GetStringFUTF16( + IDS_SATURATED_BADGE_CONTENT, base::FormatNumber(99))); + } + + return base::UTF16ToUTF8(base::FormatNumber(badge_content.value())); +} +#endif + } // namespace -void BadgeServiceDelegate::SetBadge(content::WebContents* contents) { +void BadgeServiceDelegate::SetBadge(content::WebContents* contents, + base::Optional<uint64_t> badge_content) { #if defined(OS_WIN) Browser* browser = chrome::FindBrowserWithWebContents(contents); auto* window = browser->window()->GetNativeWindow(); - chrome::DrawNumericTaskbarDecoration(window); + chrome::DrawTaskbarDecorationString(window, GetBadgeString(badge_content)); #elif defined(OS_MACOSX) - SetAppShimBadgeLabel(contents, "•"); + SetAppShimBadgeLabel(contents, GetBadgeString(badge_content)); #endif }
diff --git a/chrome/browser/ui/views/feature_promos/reopen_tab_promo_controller.cc b/chrome/browser/ui/views/feature_promos/reopen_tab_promo_controller.cc index 9d4bc99..2345810 100644 --- a/chrome/browser/ui/views/feature_promos/reopen_tab_promo_controller.cc +++ b/chrome/browser/ui/views/feature_promos/reopen_tab_promo_controller.cc
@@ -43,8 +43,11 @@ } void ReopenTabPromoController::OnMenuOpened() { - // The user followed the promo and opened the menu. Now, we highlight the - // history item and observe for the history submenu opening. + // The user followed the promo and opened the menu. First, we close the promo + // bubble since it doesn't automatically close on click. Then, we highlight + // the history item and observe for the history submenu opening. + promo_bubble_->GetWidget()->Close(); + BrowserAppMenuButton* app_menu_button = browser_view_->toolbar()->app_menu_button(); app_menu_button->RemoveMenuListener(this); @@ -59,6 +62,7 @@ void ReopenTabPromoController::OnWidgetDestroying(views::Widget* widget) { DCHECK(promo_bubble_); + promo_bubble_ = nullptr; // If the menu isn't showing, that means the promo bubble timed out. We should // notify our IPH service that help was dismissed.
diff --git a/chrome/browser/ui/views/frame/taskbar_decorator_win.cc b/chrome/browser/ui/views/frame/taskbar_decorator_win.cc index 0f7e6d9a..0d701ed 100644 --- a/chrome/browser/ui/views/frame/taskbar_decorator_win.cc +++ b/chrome/browser/ui/views/frame/taskbar_decorator_win.cc
@@ -97,7 +97,8 @@ } // namespace -void DrawNumericTaskbarDecoration(gfx::NativeWindow window) { +void DrawTaskbarDecorationString(gfx::NativeWindow window, + const std::string& content) { HWND hwnd = views::HWNDForNativeWindow(window); // This is the color used by the Windows 10 Badge API, for platform @@ -105,8 +106,12 @@ constexpr int kBackgroundColor = SkColorSetRGB(0x26, 0x25, 0x2D); constexpr int kForegroundColor = SK_ColorWHITE; constexpr int kRadius = kOverlayIconSize / 2; - constexpr int kTextSize = 12; // Fits nicely into our 16x16px icon. - const std::string kFallbackBadge = "•"; + // The minimum gap to have between our content and the edge of the badge. + constexpr int kMinMargin = 3; + // The amount of space we have to render the icon. + constexpr int kMaxBounds = kOverlayIconSize - 2 * kMinMargin; + constexpr int kMaxTextSize = 24; // Max size for our text. + constexpr int kMinTextSize = 7; // Min size for our text. auto badge = std::make_unique<SkBitmap>(); badge->allocN32Pixels(kOverlayIconSize, kOverlayIconSize); @@ -123,17 +128,18 @@ paint.reset(); paint.setAntiAlias(true); paint.setColor(kForegroundColor); - paint.setTextSize(kTextSize); SkRect bounds; - paint.measureText(kFallbackBadge.c_str(), kFallbackBadge.size(), &bounds); + int text_size = kMaxTextSize; + // Find the largest |text_size| larger than |kMinTextSize| in which + // |content| fits into our 16x16px icon, with margins. + do { + paint.setTextSize(text_size--); + paint.measureText(content.c_str(), content.size(), &bounds); + } while (text_size >= kMinTextSize && + (bounds.width() > kMaxBounds || bounds.height() > kMaxBounds)); - // Text automatically has an offset applied to it, which needs to be removed - // in order to centre text. - // TODO(harrisjay): Draw a number instead of the '•' when we update - // the Mojo bindings for the BadgeService to accept badge contents. - // See http://crbug.com/719176 - canvas.drawText(kFallbackBadge.c_str(), kFallbackBadge.size(), + canvas.drawText(content.c_str(), content.size(), kRadius - bounds.width() / 2 - bounds.x(), kRadius - bounds.height() / 2 - bounds.y(), paint);
diff --git a/chrome/browser/ui/views/frame/taskbar_decorator_win.h b/chrome/browser/ui/views/frame/taskbar_decorator_win.h index 33865d0..e514388b 100644 --- a/chrome/browser/ui/views/frame/taskbar_decorator_win.h +++ b/chrome/browser/ui/views/frame/taskbar_decorator_win.h
@@ -14,7 +14,8 @@ namespace chrome { // Add a numeric badge to the taskbar. -void DrawNumericTaskbarDecoration(gfx::NativeWindow window); +void DrawTaskbarDecorationString(gfx::NativeWindow window, + const std::string& content); // Draws a scaled version of the avatar in |image| on the taskbar button // associated with top level, visible |window|. Currently only implemented
diff --git a/chrome/browser/ui/views/ime_driver/ime_driver_mus.cc b/chrome/browser/ui/views/ime_driver/ime_driver_mus.cc index ca31c39..0ef98f8 100644 --- a/chrome/browser/ui/views/ime_driver/ime_driver_mus.cc +++ b/chrome/browser/ui/views/ime_driver/ime_driver_mus.cc
@@ -46,9 +46,7 @@ std::unique_ptr<RemoteTextInputClient> remote_client = std::make_unique<RemoteTextInputClient>( ws::mojom::TextInputClientPtr(std::move(details->client)), - details->text_input_type, details->text_input_mode, - details->text_direction, details->text_input_flags, - details->caret_bounds); + std::move(details->state), details->caret_bounds); mojo::MakeStrongBinding( std::make_unique<InputMethodBridge>(std::move(remote_client)), std::move(details->input_method_request));
diff --git a/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.cc b/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.cc index 982cb16..1fa07fe 100644 --- a/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.cc +++ b/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.cc
@@ -38,9 +38,9 @@ accessibility_input_method_observer_->ResetCaretBounds(); } -void InputMethodBridge::OnTextInputTypeChanged( - ui::TextInputType text_input_type) { - client_->SetTextInputType(text_input_type); +void InputMethodBridge::OnTextInputStateChanged( + ws::mojom::TextInputStatePtr text_input_state) { + client_->SetTextInputState(std::move(text_input_state)); if (IsActiveInputContextHandler(input_method_chromeos_.get())) input_method_chromeos_->OnTextInputTypeChanged(client_.get());
diff --git a/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h b/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h index 93ba1ea..c44e4db 100644 --- a/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h +++ b/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h
@@ -27,7 +27,8 @@ ~InputMethodBridge() override; // ws::mojom::InputMethod: - void OnTextInputTypeChanged(ui::TextInputType text_input_type) override; + void OnTextInputStateChanged( + ws::mojom::TextInputStatePtr text_input_state) override; void OnCaretBoundsChanged(const gfx::Rect& caret_bounds) override; void ProcessKeyEvent(std::unique_ptr<ui::Event> key_event, ProcessKeyEventCallback callback) override;
diff --git a/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos_unittest.cc b/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos_unittest.cc index 7853b915..c6004c78 100644 --- a/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos_unittest.cc +++ b/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos_unittest.cc
@@ -111,11 +111,15 @@ ws::mojom::TextInputClientPtr client_ptr; client_ = std::make_unique<TestTextInputClient>(MakeRequest(&client_ptr)); + ws::mojom::TextInputStatePtr text_input_state = + ws::mojom::TextInputState::New(); + text_input_state->text_input_type = ui::TEXT_INPUT_TYPE_TEXT; + text_input_state->text_input_mode = ui::TEXT_INPUT_MODE_DEFAULT; + text_input_state->text_direction = base::i18n::LEFT_TO_RIGHT; + text_input_state->text_input_flags = 0; input_method_ = std::make_unique<InputMethodBridge>( std::make_unique<RemoteTextInputClient>( - std::move(client_ptr), ui::TEXT_INPUT_TYPE_TEXT, - ui::TEXT_INPUT_MODE_DEFAULT, base::i18n::LEFT_TO_RIGHT, 0, - gfx::Rect())); + std::move(client_ptr), std::move(text_input_state), gfx::Rect())); } bool ProcessKeyEvent(std::unique_ptr<ui::Event> event) {
diff --git a/chrome/browser/ui/views/ime_driver/remote_text_input_client.cc b/chrome/browser/ui/views/ime_driver/remote_text_input_client.cc index 0ff96ed..f6781f9 100644 --- a/chrome/browser/ui/views/ime_driver/remote_text_input_client.cc +++ b/chrome/browser/ui/views/ime_driver/remote_text_input_client.cc
@@ -10,16 +10,10 @@ RemoteTextInputClient::RemoteTextInputClient( ws::mojom::TextInputClientPtr remote_client, - ui::TextInputType text_input_type, - ui::TextInputMode text_input_mode, - base::i18n::TextDirection text_direction, - int text_input_flags, + ws::mojom::TextInputStatePtr text_input_state, gfx::Rect caret_bounds) : remote_client_(std::move(remote_client)), - text_input_type_(text_input_type), - text_input_mode_(text_input_mode), - text_direction_(text_direction), - text_input_flags_(text_input_flags), + text_input_state_(std::move(text_input_state)), caret_bounds_(caret_bounds) {} RemoteTextInputClient::~RemoteTextInputClient() { @@ -27,9 +21,9 @@ RunNextPendingCallback(false); } -void RemoteTextInputClient::SetTextInputType( - ui::TextInputType text_input_type) { - text_input_type_ = text_input_type; +void RemoteTextInputClient::SetTextInputState( + ws::mojom::TextInputStatePtr text_input_state) { + text_input_state_ = std::move(text_input_state); } void RemoteTextInputClient::SetCaretBounds(const gfx::Rect& caret_bounds) { @@ -62,19 +56,19 @@ } ui::TextInputType RemoteTextInputClient::GetTextInputType() const { - return text_input_type_; + return text_input_state_->text_input_type; } ui::TextInputMode RemoteTextInputClient::GetTextInputMode() const { - return text_input_mode_; + return text_input_state_->text_input_mode; } base::i18n::TextDirection RemoteTextInputClient::GetTextDirection() const { - return text_direction_; + return text_input_state_->text_direction; } int RemoteTextInputClient::GetTextInputFlags() const { - return text_input_flags_; + return text_input_state_->text_input_flags; } bool RemoteTextInputClient::CanComposeInline() const {
diff --git a/chrome/browser/ui/views/ime_driver/remote_text_input_client.h b/chrome/browser/ui/views/ime_driver/remote_text_input_client.h index 6bcd332d..5f99d57 100644 --- a/chrome/browser/ui/views/ime_driver/remote_text_input_client.h +++ b/chrome/browser/ui/views/ime_driver/remote_text_input_client.h
@@ -18,14 +18,11 @@ public ui::internal::InputMethodDelegate { public: RemoteTextInputClient(ws::mojom::TextInputClientPtr remote_client, - ui::TextInputType text_input_type, - ui::TextInputMode text_input_mode, - base::i18n::TextDirection text_direction, - int text_input_flags, + ws::mojom::TextInputStatePtr text_input_state, gfx::Rect caret_bounds); ~RemoteTextInputClient() override; - void SetTextInputType(ui::TextInputType text_input_type); + void SetTextInputState(ws::mojom::TextInputStatePtr text_input_state); void SetCaretBounds(const gfx::Rect& caret_bounds); private: @@ -75,10 +72,7 @@ void RunNextPendingCallback(bool completed); ws::mojom::TextInputClientPtr remote_client_; - ui::TextInputType text_input_type_; - ui::TextInputMode text_input_mode_; - base::i18n::TextDirection text_direction_; - int text_input_flags_; + ws::mojom::TextInputStatePtr text_input_state_; gfx::Rect caret_bounds_; // Callbacks supplied to DispatchKeyEventPostIME() are added here. When the
diff --git a/chrome/browser/ui/views/ime_driver/simple_input_method.cc b/chrome/browser/ui/views/ime_driver/simple_input_method.cc index dcde6e6..fb1d795 100644 --- a/chrome/browser/ui/views/ime_driver/simple_input_method.cc +++ b/chrome/browser/ui/views/ime_driver/simple_input_method.cc
@@ -10,8 +10,8 @@ SimpleInputMethod::~SimpleInputMethod() {} -void SimpleInputMethod::OnTextInputTypeChanged( - ui::TextInputType text_input_type) { +void SimpleInputMethod::OnTextInputStateChanged( + ws::mojom::TextInputStatePtr text_input_state) { NOTIMPLEMENTED_LOG_ONCE(); }
diff --git a/chrome/browser/ui/views/ime_driver/simple_input_method.h b/chrome/browser/ui/views/ime_driver/simple_input_method.h index 8d0f0a23..62bda96 100644 --- a/chrome/browser/ui/views/ime_driver/simple_input_method.h +++ b/chrome/browser/ui/views/ime_driver/simple_input_method.h
@@ -17,7 +17,8 @@ ~SimpleInputMethod() override; // ws::mojom::InputMethod: - void OnTextInputTypeChanged(ui::TextInputType text_input_type) override; + void OnTextInputStateChanged( + ws::mojom::TextInputStatePtr text_input_state) override; void OnCaretBoundsChanged(const gfx::Rect& caret_bounds) override; void ProcessKeyEvent(std::unique_ptr<ui::Event> key_event, ProcessKeyEventCallback callback) override;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc index 0ea93c4..60abd552 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -133,7 +133,6 @@ saved_selection_for_focus_change_(gfx::Range::InvalidRange()), ime_composing_before_change_(false), location_bar_view_(location_bar), - ime_candidate_window_open_(false), is_mouse_pressed_(false), select_all_on_mouse_release_(false), select_all_on_gesture_tap_(false),
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.h b/chrome/browser/ui/views/omnibox/omnibox_view_views.h index de5b6467f..f690819 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.h +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.h
@@ -104,6 +104,7 @@ void SetUserText(const base::string16& text, bool update_popup) override; void EnterKeywordModeForDefaultSearchProvider() override; + bool IsSelectAll() const override; void GetSelectionBounds(base::string16::size_type* start, base::string16::size_type* end) const override; void SelectAll(bool reversed) override; @@ -121,44 +122,21 @@ void RemovedFromWidget() override; bool ShouldDoLearning() override; - protected: // For testing only. - OmniboxPopupContentsView* GetPopupContentsView() const { + OmniboxPopupContentsView* GetPopupContentsViewForTesting() const { return popup_view_.get(); } + protected: // views::Textfield: bool IsDropCursorForInsertion() const override; private: + // TODO(tommycli): Remove the rest of these friends after porting these + // browser tests to unit tests. FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, CloseOmniboxPopupOnTextDrag); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, FriendlyAccessibleLabel); - FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, AccessiblePopup); - 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, - NegligibleDragKeepsElisions); - FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsSteadyStateElisionsTest, - CaretPlacementByMouse); - FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsSteadyStateElisionsTest, - MouseDoubleClick); - FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsSteadyStateElisionsTest, - MouseTripleClick); - FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsSteadyStateElisionsTest, - MouseClickDrag); - FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsSteadyStateElisionsTest, - MouseClickDragToBeginningSelectingText); - FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsSteadyStateElisionsTest, - MouseClickDragToBeginningSelectingURL); - FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsSteadyStateElisionsTest, - MouseDoubleClickDrag); - friend class OmniboxViewViewsTest; - friend class OmniboxViewViewsSteadyStateElisionsTest; enum class UnelisionGesture { HOME_KEY_PRESSED, @@ -217,7 +195,6 @@ bool update_popup, bool notify_text_changed) override; void SetCaretPos(size_t caret_pos) override; - bool IsSelectAll() const override; void UpdatePopup() override; void ApplyCaretVisibility() override; void OnTemporaryTextMaybeChanged(const base::string16& display_text, @@ -322,10 +299,12 @@ // |location_bar_view_| can be NULL in tests. LocationBarView* location_bar_view_; +#if defined(OS_CHROMEOS) // True if the IME candidate window is open. When this is true, we want to // avoid showing the popup. So far, the candidate window is detected only // on Chrome OS. - bool ime_candidate_window_open_; + bool ime_candidate_window_open_ = false; +#endif // True if any mouse button is currently depressed. bool is_mouse_pressed_;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc index 223ed1e..5a3814c 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc
@@ -626,7 +626,7 @@ match.allowed_to_be_default_match = true; OmniboxPopupContentsView* popup_view = - omnibox_view_views->GetPopupContentsView(); + omnibox_view_views->GetPopupContentsViewForTesting(); ui::AXNodeData popup_node_data_1; popup_view->GetAccessibleNodeData(&popup_node_data_1); EXPECT_FALSE(popup_node_data_1.HasState(ax::mojom::State::kExpanded));
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 d95b2a6..28844f6 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
@@ -210,7 +210,13 @@ TestLocationBarModel* location_bar_model() { return &location_bar_model_; } TestingOmniboxView* omnibox_view() const { return omnibox_view_; } + + // TODO(tommycli): These base class accessors exist because Textfield and + // OmniboxView both hide member functions that were public in base classes. + // Remove these after we stop doing that. views::Textfield* omnibox_textfield() const { return omnibox_view(); } + views::View* omnibox_textfield_view() const { return omnibox_view(); } + ui::TextEditCommand scheduled_text_edit_command() const { return test_api_->scheduled_text_edit_command(); } @@ -410,7 +416,7 @@ // SetWindowTextAndCaretPos to scroll such that the start of the string is // on-screen. Because the domain is RTL, this scrolls to an offset greater // than 0. - omnibox_view()->OnFocus(); + omnibox_textfield()->OnFocus(); const base::string16 kContentsRtl = base::WideToUTF16(L"\x05e8\x05e2.\x05e7\x05d5\x05dd/0123/abcd"); static_cast<OmniboxView*>(omnibox_view()) @@ -426,7 +432,7 @@ // Now enter blurred mode, where the text should be elided to 60px. This means // the string itself is truncated. Scrolling would therefore mean the text is // off-screen. Ensure that the horizontal scrolling has been reset to 0. - omnibox_view()->OnBlur(); + omnibox_textfield()->OnBlur(); EXPECT_EQ(gfx::ELIDE_TAIL, render_text->elide_behavior()); EXPECT_EQ(0, render_text->GetUpdatedDisplayOffset().x()); EXPECT_FALSE(omnibox_view()->IsSelectAll()); @@ -606,14 +612,13 @@ // beginning of the RenderText. void SendMouseClick(int x_offset) { gfx::Point point = GetPointInTextAtXOffset(x_offset); - omnibox_view()->OnMousePressed( + omnibox_textfield()->OnMousePressed( CreateMouseEvent(ui::ET_MOUSE_PRESSED, point)); - omnibox_view()->OnMouseReleased( + omnibox_textfield()->OnMouseReleased( CreateMouseEvent(ui::ET_MOUSE_RELEASED, point)); } // Used to access members that are marked private in views::TextField. - views::View* omnibox_textfield_view() { return omnibox_view(); } base::SimpleTestTickClock* clock() { return &clock_; } private: @@ -670,19 +675,19 @@ return; ui::GestureEvent tap_down(0, 0, 0, ui::EventTimeForNow(), ui::GestureEventDetails(ui::ET_GESTURE_TAP_DOWN)); - omnibox_textfield_view()->OnGestureEvent(&tap_down); + omnibox_textfield()->OnGestureEvent(&tap_down); // Select all on first tap. ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP); tap_details.set_tap_count(1); ui::GestureEvent tap(0, 0, 0, ui::EventTimeForNow(), tap_details); - omnibox_textfield_view()->OnGestureEvent(&tap); + omnibox_textfield()->OnGestureEvent(&tap); EXPECT_TRUE(omnibox_view()->IsSelectAll()); EXPECT_TRUE(IsElidedUrlDisplayed()); // Unelide on second tap (cursor placement). - omnibox_textfield_view()->OnGestureEvent(&tap); + omnibox_textfield()->OnGestureEvent(&tap); ExpectFullUrlDisplayed(); } @@ -698,15 +703,15 @@ TEST_F(OmniboxViewViewsSteadyStateElisionsTest, NegligibleDragKeepsElisions) { gfx::Point click_point = GetPointInTextAtXOffset(2 * kCharacterWidth); - omnibox_view()->OnMousePressed( + omnibox_textfield()->OnMousePressed( CreateMouseEvent(ui::ET_MOUSE_PRESSED, click_point)); // Offset the drag and release point by an insignificant 2 px. gfx::Point drag_point = click_point; drag_point.Offset(2, 0); - omnibox_view()->OnMouseDragged( + omnibox_textfield()->OnMouseDragged( CreateMouseEvent(ui::ET_MOUSE_DRAGGED, drag_point)); - omnibox_view()->OnMouseReleased( + omnibox_textfield()->OnMouseReleased( CreateMouseEvent(ui::ET_MOUSE_RELEASED, drag_point)); // Expect that after a negligible drag and release, everything is selected. @@ -723,10 +728,10 @@ clock()->Advance(base::TimeDelta::FromSeconds(5)); // Second click should unelide only on mouse release. - omnibox_view()->OnMousePressed(CreateMouseEvent( + omnibox_textfield()->OnMousePressed(CreateMouseEvent( ui::ET_MOUSE_PRESSED, GetPointInTextAtXOffset(2 * kCharacterWidth))); EXPECT_TRUE(IsElidedUrlDisplayed()); - omnibox_view()->OnMouseReleased(CreateMouseEvent( + omnibox_textfield()->OnMouseReleased(CreateMouseEvent( ui::ET_MOUSE_RELEASED, GetPointInTextAtXOffset(2 * kCharacterWidth))); ExpectFullUrlDisplayed(); @@ -744,7 +749,7 @@ // Second click without advancing the clock should be a double-click, which // should do a single word selection and unelide the text on mousedown. - omnibox_view()->OnMousePressed(CreateMouseEvent( + omnibox_textfield()->OnMousePressed(CreateMouseEvent( ui::ET_MOUSE_PRESSED, GetPointInTextAtXOffset(4 * kCharacterWidth))); ExpectFullUrlDisplayed(); @@ -772,12 +777,12 @@ } TEST_F(OmniboxViewViewsSteadyStateElisionsTest, MouseClickDrag) { - omnibox_view()->OnMousePressed(CreateMouseEvent( + omnibox_textfield()->OnMousePressed(CreateMouseEvent( ui::ET_MOUSE_PRESSED, GetPointInTextAtXOffset(2 * kCharacterWidth))); EXPECT_TRUE(IsElidedUrlDisplayed()); // Expect that during the drag, the URL is still elided. - omnibox_view()->OnMouseDragged(CreateMouseEvent( + omnibox_textfield()->OnMouseDragged(CreateMouseEvent( ui::ET_MOUSE_DRAGGED, GetPointInTextAtXOffset(4 * kCharacterWidth))); EXPECT_TRUE(IsElidedUrlDisplayed()); @@ -787,7 +792,7 @@ EXPECT_EQ(2U, start); EXPECT_EQ(4U, end); - omnibox_view()->OnMouseReleased(CreateMouseEvent( + omnibox_textfield()->OnMouseReleased(CreateMouseEvent( ui::ET_MOUSE_RELEASED, GetPointInTextAtXOffset(4 * kCharacterWidth))); ExpectFullUrlDisplayed(); @@ -801,11 +806,11 @@ TEST_F(OmniboxViewViewsSteadyStateElisionsTest, MouseClickDragToBeginningSelectingText) { // Backwards drag-select this portion of the elided URL: |exam|ple.com - omnibox_view()->OnMousePressed(CreateMouseEvent( + omnibox_textfield()->OnMousePressed(CreateMouseEvent( ui::ET_MOUSE_PRESSED, GetPointInTextAtXOffset(4 * kCharacterWidth))); - omnibox_view()->OnMouseDragged(CreateMouseEvent( + omnibox_textfield()->OnMouseDragged(CreateMouseEvent( ui::ET_MOUSE_DRAGGED, GetPointInTextAtXOffset(0 * kCharacterWidth))); - omnibox_view()->OnMouseReleased(CreateMouseEvent( + omnibox_textfield()->OnMouseReleased(CreateMouseEvent( ui::ET_MOUSE_RELEASED, GetPointInTextAtXOffset(0 * kCharacterWidth))); ExpectFullUrlDisplayed(); @@ -821,11 +826,11 @@ TEST_F(OmniboxViewViewsSteadyStateElisionsTest, MouseClickDragToBeginningSelectingURL) { // Backwards drag-select this portion of the elided URL: |example.co|m - omnibox_view()->OnMousePressed(CreateMouseEvent( + omnibox_textfield()->OnMousePressed(CreateMouseEvent( ui::ET_MOUSE_PRESSED, GetPointInTextAtXOffset(10 * kCharacterWidth))); - omnibox_view()->OnMouseDragged(CreateMouseEvent( + omnibox_textfield()->OnMouseDragged(CreateMouseEvent( ui::ET_MOUSE_DRAGGED, GetPointInTextAtXOffset(0 * kCharacterWidth))); - omnibox_view()->OnMouseReleased(CreateMouseEvent( + omnibox_textfield()->OnMouseReleased(CreateMouseEvent( ui::ET_MOUSE_RELEASED, GetPointInTextAtXOffset(0 * kCharacterWidth))); ExpectFullUrlDisplayed(); @@ -842,7 +847,7 @@ // Expect that after a double-click after the third character of the elided // text, the text is unelided, and https://www.|example|.com is selected. SendMouseClick(4 * kCharacterWidth); - omnibox_view()->OnMousePressed(CreateMouseEvent( + omnibox_textfield()->OnMousePressed(CreateMouseEvent( ui::ET_MOUSE_PRESSED, GetPointInTextAtXOffset(4 * kCharacterWidth))); ExpectFullUrlDisplayed(); size_t start, end; @@ -855,7 +860,7 @@ // domain, so the new selection will be |https://www.example|.com. The // expected selection is backwards, since we are dragging the mouse from the // domain to the scheme. - omnibox_view()->OnMouseDragged(CreateMouseEvent( + omnibox_textfield()->OnMouseDragged(CreateMouseEvent( ui::ET_MOUSE_DRAGGED, GetPointInTextAtXOffset(2 * kCharacterWidth))); ExpectFullUrlDisplayed(); omnibox_view()->GetSelectionBounds(&start, &end); @@ -863,7 +868,7 @@ EXPECT_EQ(0U, end); // Expect the selection to stay the same after mouse-release. - omnibox_view()->OnMouseReleased(CreateMouseEvent( + omnibox_textfield()->OnMouseReleased(CreateMouseEvent( ui::ET_MOUSE_RELEASED, GetPointInTextAtXOffset(2 * kCharacterWidth))); ExpectFullUrlDisplayed(); omnibox_view()->GetSelectionBounds(&start, &end);
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc index 4f4a40f..d228af4 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -220,6 +220,7 @@ home_->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_HOME)); home_->set_id(VIEW_ID_HOME_BUTTON); home_->Init(); + home_->SizeToPreferredSize(); // No master container for this one (it is master). BrowserActionsContainer* main_container = nullptr; @@ -282,6 +283,7 @@ prefs::kShowHomeButton, browser_->profile()->GetPrefs(), base::BindRepeating(&ToolbarView::OnShowHomeButtonChanged, base::Unretained(this))); + UpdateHomeButtonVisibility(); InitLayout(); @@ -685,11 +687,6 @@ back_->SetLeadingMargin(maximized ? interior_margin.left() : 0); app_menu_button_->SetTrailingMargin(maximized ? interior_margin.right() : 0); - const bool show_home_button = - show_home_button_.GetValue() || - (browser_->is_app() && extensions::util::IsNewBookmarkAppsEnabled()); - home_->SetVisible(show_home_button); - // Cast button visibility is controlled externally. } @@ -817,6 +814,14 @@ } void ToolbarView::OnShowHomeButtonChanged() { + UpdateHomeButtonVisibility(); Layout(); SchedulePaint(); } + +void ToolbarView::UpdateHomeButtonVisibility() { + const bool show_home_button = + show_home_button_.GetValue() || + (browser_->is_app() && extensions::util::IsNewBookmarkAppsEnabled()); + home_->SetVisible(show_home_button); +}
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.h b/chrome/browser/ui/views/toolbar/toolbar_view.h index 740dabc..2db078ed 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_view.h +++ b/chrome/browser/ui/views/toolbar/toolbar_view.h
@@ -242,6 +242,7 @@ void ShowOutdatedInstallNotification(bool auto_update_enabled); void OnShowHomeButtonChanged(); + void UpdateHomeButtonVisibility(); gfx::SlideAnimation size_animation_{this};
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view_interactive_uitest.cc b/chrome/browser/ui/views/toolbar/toolbar_view_interactive_uitest.cc index 8f3c1c9..a984bb7 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_view_interactive_uitest.cc
@@ -125,7 +125,7 @@ void ToolbarViewInteractiveUITest::FinishDragAndDrop( base::Closure quit_closure) { - base::ScopedAllowBlockingForTesting allow_thread_join; + base::ScopedAllowBaseSyncPrimitivesForTesting allow_thread_join; dnd_thread_.reset(); TestWhileInDragOperation(); ui_controls::SendMouseEventsNotifyWhenDone(ui_controls::LEFT, ui_controls::UP,
diff --git a/chrome/browser/ui/webui/app_management/app_management_ui.cc b/chrome/browser/ui/webui/app_management/app_management_ui.cc index 32027df..a72a2661 100644 --- a/chrome/browser/ui/webui/app_management/app_management_ui.cc +++ b/chrome/browser/ui/webui/app_management/app_management_ui.cc
@@ -78,6 +78,8 @@ IDR_APP_MANAGEMENT_PWA_PERMISSION_VIEW_JS); source->AddResourcePath("reducers.html", IDR_APP_MANAGEMENT_REDUCERS_HTML); source->AddResourcePath("reducers.js", IDR_APP_MANAGEMENT_REDUCERS_JS); + source->AddResourcePath("router.html", IDR_APP_MANAGEMENT_ROUTER_HTML); + source->AddResourcePath("router.js", IDR_APP_MANAGEMENT_ROUTER_JS); source->AddResourcePath("shared_style.html", IDR_APP_MANAGEMENT_SHARED_STYLE_HTML); source->AddResourcePath("shared_vars.html",
diff --git a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.cc b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.cc index 1a36695a..ef2ba539 100644 --- a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.cc +++ b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.cc
@@ -20,6 +20,7 @@ #include "content/public/browser/host_zoom_map.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" +#include "net/base/url_util.h" #include "ui/views/widget/widget.h" namespace chromeos { @@ -30,6 +31,15 @@ constexpr int kAssistantOptInDialogWidth = 768; constexpr int kAssistantOptInDialogHeight = 640; +constexpr char kFlowTypeParamKey[] = "flow-type"; + +GURL CreateAssistantOptInURL(ash::mojom::FlowType type) { + // TODO(updowndota): Directly use mojom enum types in js. + auto gurl = net::AppendOrReplaceQueryParameter( + GURL(chrome::kChromeUIAssistantOptInURL), kFlowTypeParamKey, + std::to_string(static_cast<int>(type))); + return gurl; +} } // namespace @@ -66,9 +76,11 @@ // static void AssistantOptInDialog::Show( + ash::mojom::FlowType type, ash::mojom::AssistantSetup::StartAssistantOptInFlowCallback callback) { DCHECK(!is_active); - AssistantOptInDialog* dialog = new AssistantOptInDialog(std::move(callback)); + AssistantOptInDialog* dialog = + new AssistantOptInDialog(type, std::move(callback)); views::Widget::InitParams extra_params = ash_util::GetFramelessInitParams(); chrome::ShowWebDialogWithParams(nullptr /* parent */, @@ -82,9 +94,9 @@ } AssistantOptInDialog::AssistantOptInDialog( + ash::mojom::FlowType type, ash::mojom::AssistantSetup::StartAssistantOptInFlowCallback callback) - : SystemWebDialogDelegate(GURL(chrome::kChromeUIAssistantOptInURL), - base::string16()), + : SystemWebDialogDelegate(CreateAssistantOptInURL(type), base::string16()), callback_(std::move(callback)) { DCHECK(!is_active); is_active = true;
diff --git a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.h b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.h index a466734..99cf45c 100644 --- a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.h +++ b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.h
@@ -35,14 +35,17 @@ class AssistantOptInDialog : public SystemWebDialogDelegate { public: // Shows the assistant optin dialog. - static void Show(ash::mojom::AssistantSetup::StartAssistantOptInFlowCallback - callback = base::DoNothing()); + static void Show( + ash::mojom::FlowType type = ash::mojom::FlowType::CONSENT_FLOW, + ash::mojom::AssistantSetup::StartAssistantOptInFlowCallback callback = + base::DoNothing()); // Returns whether the dialog is being shown. static bool IsActive(); protected: - explicit AssistantOptInDialog( + AssistantOptInDialog( + ash::mojom::FlowType type, ash::mojom::AssistantSetup::StartAssistantOptInFlowCallback callback); ~AssistantOptInDialog() override;
diff --git a/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc index bd0b70b..4ee783f 100644 --- a/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc
@@ -494,10 +494,12 @@ CallJSWithPrefix("closeDialog"); } -void AssistantOptInFlowScreenHandler::HandleFlowInitialized() { +void AssistantOptInFlowScreenHandler::HandleFlowInitialized( + const int flow_type) { initialized_ = true; - if (settings_manager_.is_bound()) { + if (settings_manager_.is_bound() && + flow_type == static_cast<int>(ash::mojom::FlowType::CONSENT_FLOW)) { SendGetSettingsRequest(); } }
diff --git a/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.h index 5f74d3c7..f62cf37 100644 --- a/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.h
@@ -8,6 +8,7 @@ #include <memory> #include <string> +#include "ash/public/interfaces/assistant_setup.mojom.h" #include "base/macros.h" #include "chrome/browser/chromeos/arc/voice_interaction/voice_interaction_controller_client.h" #include "chrome/browser/chromeos/login/screens/assistant_optin_flow_screen_view.h" @@ -88,7 +89,7 @@ void HandleLoadingTimeout(); void HandleHotwordResult(bool enable_hotword); void HandleFlowFinished(); - void HandleFlowInitialized(); + void HandleFlowInitialized(const int flow_type); AssistantOptInFlowScreen* screen_ = nullptr;
diff --git a/chrome/browser/ui/webui/extensions/extensions_ui.cc b/chrome/browser/ui/webui/extensions/extensions_ui.cc index 7adcc4d..c5e41e6d 100644 --- a/chrome/browser/ui/webui/extensions/extensions_ui.cc +++ b/chrome/browser/ui/webui/extensions/extensions_ui.cc
@@ -184,6 +184,7 @@ {"accessibilityErrorMultiLine", IDS_MD_EXTENSIONS_ACCESSIBILITY_ERROR_MULTI_LINE}, {"activityLogPageHeading", IDS_MD_EXTENSIONS_ACTIVITY_LOG_PAGE_HEADING}, + {"activityLogSearchLabel", IDS_MD_EXTENSIONS_ACTIVITY_LOG_SEARCH_LABEL}, {"appIcon", IDS_MD_EXTENSIONS_APP_ICON}, {"extensionIcon", IDS_MD_EXTENSIONS_EXTENSION_ICON}, {"extensionA11yAssociation", IDS_MD_EXTENSIONS_EXTENSION_A11Y_ASSOCIATION},
diff --git a/chrome/browser/ui/webui/version_handler_win.cc b/chrome/browser/ui/webui/version_handler_win.cc new file mode 100644 index 0000000..9e1dd10 --- /dev/null +++ b/chrome/browser/ui/webui/version_handler_win.cc
@@ -0,0 +1,94 @@ +// 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/version_handler_win.h" + +#include "base/bind.h" +#include "base/strings/stringprintf.h" +#include "base/task/post_task.h" +#include "base/win/windows_version.h" +#include "content/public/browser/web_ui.h" + +namespace { + +// rerurn marketing version of Windows OS +// may return an empty string if values returned by base::win::OSinfo +// are not defined below +std::string FullWindowsVersion() { + std::string version; + base::win::OSInfo* gi = base::win::OSInfo::GetInstance(); + const int major = gi->version_number().major; + const int minor = gi->version_number().minor; + const int build = gi->version_number().build; + const int patch = gi->version_number().patch; + // Server or Desktop + const bool server = + gi->version_type() == base::win::VersionType::SUITE_SERVER; + // Service Pack + const std::string sp = gi->service_pack_str(); + + if (major == 10) { + version += (server) ? "Server OS" : "10 OS"; + } else if (major == 6) { + switch (minor) { + case 0: + // Windows Vista or Server 2008 + version += (server) ? "Server 2008 " : "Vista "; + version += sp; + break; + case 1: + // Windows 7 or Server 2008 R2 + version += (server) ? "Server 2008 R2 " : "7 "; + version += sp; + break; + case 2: + // Windows 8 or Server 2012 + version += (server) ? "Server 2012" : "8"; + break; + case 3: + // Windows 8.1 or Server 2012 R2 + version += (server) ? "Server 2012 R2" : "8.1"; + break; + default: + // unknown version + return base::StringPrintf("unknown version 6.%d", minor); + } + } else if ((major == 5) && (minor > 0)) { + // Windows XP or Server 2003 + version += (server) ? "Server 2003 " : "XP "; + version += sp; + } else { + // unknown version + return base::StringPrintf("unknown version %d.%d", major, minor); + } + if (patch > 0) + version += base::StringPrintf(" Build %d.%d", build, patch); + else + version += base::StringPrintf(" Build %d", build); + return version; +} + +} // namespace + +VersionHandlerWindows::VersionHandlerWindows() : weak_factory_(this) {} + +VersionHandlerWindows::~VersionHandlerWindows() {} + +void VersionHandlerWindows::HandleRequestVersionInfo( + const base::ListValue* args) { + // Start the asynchronous load of the versions. + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + base::BindOnce(&FullWindowsVersion), + base::BindOnce(&VersionHandlerWindows::OnVersion, + weak_factory_.GetWeakPtr())); + + // Parent class takes care of the rest. + VersionHandler::HandleRequestVersionInfo(args); +} + +void VersionHandlerWindows::OnVersion(const std::string& version) { + base::Value arg(version); + CallJavascriptFunction("returnOsVersion", arg); +}
diff --git a/chrome/browser/ui/webui/version_handler_win.h b/chrome/browser/ui/webui/version_handler_win.h new file mode 100644 index 0000000..52536db --- /dev/null +++ b/chrome/browser/ui/webui/version_handler_win.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_UI_WEBUI_VERSION_HANDLER_WIN_H_ +#define CHROME_BROWSER_UI_WEBUI_VERSION_HANDLER_WIN_H_ + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "chrome/browser/ui/webui/version_handler.h" + +// VersionHandlerWindows is responsible for loading the Windows OS version. +class VersionHandlerWindows : public VersionHandler { + public: + VersionHandlerWindows(); + ~VersionHandlerWindows() override; + + // VersionHandler overrides: + void HandleRequestVersionInfo(const base::ListValue* args) override; + + // Callbacks from windows::VersionLoader. + void OnVersion(const std::string& version); + + private: + base::WeakPtrFactory<VersionHandlerWindows> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(VersionHandlerWindows); +}; + +#endif // CHROME_BROWSER_UI_WEBUI_VERSION_HANDLER_WIN_H_
diff --git a/chrome/browser/ui/webui/version_handler_win_unittest.cc b/chrome/browser/ui/webui/version_handler_win_unittest.cc new file mode 100644 index 0000000..074c79fa --- /dev/null +++ b/chrome/browser/ui/webui/version_handler_win_unittest.cc
@@ -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. + +#include "chrome/browser/ui/webui/version_handler_win.h" + +#include "base/test/scoped_os_info_override_win.h" +#include "base/test/test_reg_util_win.h" +#include "base/win/registry.h" +#include "chrome/browser/ui/webui/version_handler_win.cc" +#include "testing/gtest/include/gtest/gtest.h" + +class WebUIWindowsVersion : public testing::Test { + protected: + base::win::RegKey ubr_key; + + void SetUp() override { + ASSERT_NO_FATAL_FAILURE(registry_override_manager_.OverrideRegistry(root)); + ubr_key.Create(root, ubr_loc, KEY_ALL_ACCESS); + EXPECT_TRUE(ubr_key.Valid()); + } + void TearDown() override { + ubr_key.DeleteKey(ubr_loc); + ubr_key.Close(); + } + + private: + const HKEY root = HKEY_LOCAL_MACHINE; + // Win10 UBR, see base::win::OSInfo + const wchar_t* ubr_loc = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"; + registry_util::RegistryOverrideManager registry_override_manager_; +}; + +TEST_F(WebUIWindowsVersion, Win10Pro) { + // set Windows Registry Key UBR + ubr_key.WriteValue(L"UBR", 555); + // override base::win::OSInfo + base::test::ScopedOSInfoOverride os( + base::test::ScopedOSInfoOverride::Type::kWin10Pro); + EXPECT_EQ(FullWindowsVersion(), "10 OS Build 15063.555"); +} + +TEST_F(WebUIWindowsVersion, WinServer2016) { + ubr_key.WriteValue(L"UBR", 1555); + base::test::ScopedOSInfoOverride os( + base::test::ScopedOSInfoOverride::Type::kWinServer2016); + EXPECT_EQ(FullWindowsVersion(), "Server OS Build 17134.1555"); +} + +TEST_F(WebUIWindowsVersion, Win81Pro) { + ubr_key.WriteValue(L"UBR", 0UL); + base::test::ScopedOSInfoOverride os( + base::test::ScopedOSInfoOverride::Type::kWin81Pro); + EXPECT_EQ(FullWindowsVersion(), "8.1 Build 9600"); +} + +TEST_F(WebUIWindowsVersion, WinServer2012R2) { + ubr_key.WriteValue(L"UBR", 0UL); + base::test::ScopedOSInfoOverride os( + base::test::ScopedOSInfoOverride::Type::kWinServer2012R2); + EXPECT_EQ(FullWindowsVersion(), "Server 2012 R2 Build 9600"); +} + +TEST_F(WebUIWindowsVersion, Win7ProSP1) { + ubr_key.WriteValue(L"UBR", 0UL); + base::test::ScopedOSInfoOverride os( + base::test::ScopedOSInfoOverride::Type::kWin7ProSP1); + EXPECT_EQ(FullWindowsVersion(), "7 Service Pack 1 Build 7601"); +}
diff --git a/chrome/browser/ui/webui/version_ui.cc b/chrome/browser/ui/webui/version_ui.cc index 9814af2..715b6b0 100644 --- a/chrome/browser/ui/webui/version_ui.cc +++ b/chrome/browser/ui/webui/version_ui.cc
@@ -39,6 +39,7 @@ #endif #if defined(OS_WIN) +#include "chrome/browser/ui/webui/version_handler_win.h" #include "chrome/install_static/install_details.h" #endif @@ -165,6 +166,8 @@ #if defined(OS_CHROMEOS) web_ui->AddMessageHandler(std::make_unique<VersionHandlerChromeOS>()); +#elif defined(OS_WIN) + web_ui->AddMessageHandler(std::make_unique<VersionHandlerWindows>()); #else web_ui->AddMessageHandler(std::make_unique<VersionHandler>()); #endif @@ -177,5 +180,4 @@ WebUIDataSource::Add(profile, CreateVersionUIDataSource()); } -VersionUI::~VersionUI() { -} +VersionUI::~VersionUI() {}
diff --git a/chrome/browser/usb/web_usb_detector.cc b/chrome/browser/usb/web_usb_detector.cc index ef2d1f0..4d92dfc 100644 --- a/chrome/browser/usb/web_usb_detector.cc +++ b/chrome/browser/usb/web_usb_detector.cc
@@ -112,7 +112,9 @@ if (tab_strip_model->empty() || !selection.active_tab_changed()) return; - if (selection.new_contents->GetURL() == landing_page_) { + if (base::StartsWith(selection.new_contents->GetURL().spec(), + landing_page_.spec(), + base::CompareCase::INSENSITIVE_ASCII)) { // If the disposition is not already set, go ahead and set it. if (disposition_ == WEBUSB_NOTIFICATION_CLOSED) disposition_ = WEBUSB_NOTIFICATION_CLOSED_MANUAL_NAVIGATION; @@ -129,7 +131,8 @@ Browser* browser = nullptr; auto& all_tabs = AllTabContentses(); for (auto it = all_tabs.begin(), end = all_tabs.end(); it != end; ++it) { - if (it->GetVisibleURL() == landing_page_ && + if (base::StartsWith(it->GetVisibleURL().spec(), landing_page_.spec(), + base::CompareCase::INSENSITIVE_ASCII) && (!tab_to_activate || it->GetLastActiveTime() > tab_to_activate->GetLastActiveTime())) { tab_to_activate = *it; @@ -215,8 +218,10 @@ if (!landing_page.is_valid() || !content::IsOriginSecure(landing_page)) return; - if (landing_page == GetActiveTabURL()) + if (base::StartsWith(GetActiveTabURL().spec(), landing_page.spec(), + base::CompareCase::INSENSITIVE_ASCII)) { return; + } std::string notification_id = device_info->guid;
diff --git a/chrome/browser/usb/web_usb_detector_unittest.cc b/chrome/browser/usb/web_usb_detector_unittest.cc index 6efda470..c3d34aea 100644 --- a/chrome/browser/usb/web_usb_detector_unittest.cc +++ b/chrome/browser/usb/web_usb_detector_unittest.cc
@@ -48,6 +48,7 @@ const char* kLandingPage_1 = "https://www.google.com/A"; const char* kLandingPage_2 = "https://www.google.com/B"; const char* kLandingPage_3 = "https://www.google.com/C"; +const char* kLandingPage_1_fuzzed = "https://www.google.com/A/fuzzy"; } // namespace @@ -565,4 +566,75 @@ EXPECT_FALSE(display_service_->GetNotification(guid_1)); histogram_tester.ExpectUniqueSample("WebUsb.NotificationClosed", 2, 1); } + +TEST_F(WebUsbDetectorTest, UsbDeviceAddedBeforeActiveTabFuzzyUrlIsLandingPage) { + GURL landing_page_1(kLandingPage_1); + GURL landing_page_1_fuzzed(kLandingPage_1_fuzzed); + auto device_1 = base::MakeRefCounted<device::FakeUsbDeviceInfo>( + 0, 1, "Google", kProductName_1, "002", landing_page_1); + std::string guid_1 = device_1->guid(); + + base::HistogramTester histogram_tester; + Initialize(); + base::RunLoop().RunUntilIdle(); + + device_manager_.AddDevice(device_1); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(display_service_->GetNotification(guid_1)); + + AddTab(browser(), landing_page_1_fuzzed); + EXPECT_FALSE(display_service_->GetNotification(guid_1)); + histogram_tester.ExpectUniqueSample("WebUsb.NotificationClosed", 3, 1); +} + +TEST_F(WebUsbDetectorTest, UsbDeviceAddedWhileActiveTabFuzzyUrlIsLandingPage) { + GURL landing_page_1(kLandingPage_1); + GURL landing_page_1_fuzzed(kLandingPage_1_fuzzed); + auto device_1 = base::MakeRefCounted<device::FakeUsbDeviceInfo>( + 0, 1, "Google", kProductName_3, "002", landing_page_1); + std::string guid_1 = device_1->guid(); + + Initialize(); + base::RunLoop().RunUntilIdle(); + + AddTab(browser(), landing_page_1_fuzzed); + + device_manager_.AddDevice(device_1); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(display_service_->GetNotification(guid_1)); +} + +TEST_F(WebUsbDetectorTest, + NotificationClickedWhileInactiveTabFuzzyUrlIsLandingPage) { + GURL landing_page_1(kLandingPage_1); + GURL landing_page_1_fuzzed(kLandingPage_1_fuzzed); + GURL landing_page_2(kLandingPage_2); + auto device_1 = base::MakeRefCounted<device::FakeUsbDeviceInfo>( + 0, 1, "Google", kProductName_1, "002", landing_page_1); + std::string guid_1 = device_1->guid(); + TabStripModel* tab_strip_model = browser()->tab_strip_model(); + + base::HistogramTester histogram_tester; + Initialize(); + base::RunLoop().RunUntilIdle(); + + AddTab(browser(), landing_page_1_fuzzed); + AddTab(browser(), landing_page_2); + + device_manager_.AddDevice(device_1); + base::RunLoop().RunUntilIdle(); + base::Optional<message_center::Notification> notification_1 = + display_service_->GetNotification(guid_1); + ASSERT_TRUE(notification_1); + EXPECT_EQ(2, tab_strip_model->count()); + + notification_1->delegate()->Click(base::nullopt, base::nullopt); + EXPECT_EQ(2, tab_strip_model->count()); + content::WebContents* web_contents = + tab_strip_model->GetWebContentsAt(tab_strip_model->active_index()); + EXPECT_EQ(landing_page_1_fuzzed, web_contents->GetURL()); + EXPECT_FALSE(display_service_->GetNotification(guid_1)); + histogram_tester.ExpectUniqueSample("WebUsb.NotificationClosed", 2, 1); +} + #endif // !OS_WIN
diff --git a/chrome/browser/vr/BUILD.gn b/chrome/browser/vr/BUILD.gn index 60e60ba3..ad4f65f 100644 --- a/chrome/browser/vr/BUILD.gn +++ b/chrome/browser/vr/BUILD.gn
@@ -310,8 +310,8 @@ "win/scheduler_delegate_win.h", "win/vr_browser_renderer_thread_win.cc", "win/vr_browser_renderer_thread_win.h", - "win/vr_renderloop_host_win.cc", - "win/vr_renderloop_host_win.h", + "win/vr_ui_host_impl.cc", + "win/vr_ui_host_impl.h", ] deps += [ "//services/ws/public/cpp/gpu" ]
diff --git a/chrome/browser/vr/service/browser_xr_runtime.h b/chrome/browser/vr/service/browser_xr_runtime.h index 0755cc20..c0fa86c 100644 --- a/chrome/browser/vr/service/browser_xr_runtime.h +++ b/chrome/browser/vr/service/browser_xr_runtime.h
@@ -29,6 +29,10 @@ public: virtual void SetVRDisplayInfo( device::mojom::VRDisplayInfoPtr display_info) = 0; + + // The parameter |contents| is set when a page starts an immersive WebXR + // session. There can only be at most one active immersive session for the + // XRRuntime. Set to null when there is no active immersive session. virtual void SetWebXRWebContents(content::WebContents* contents) = 0; };
diff --git a/chrome/browser/vr/service/isolated_device_provider.cc b/chrome/browser/vr/service/isolated_device_provider.cc index 71434910..a585df2 100644 --- a/chrome/browser/vr/service/isolated_device_provider.cc +++ b/chrome/browser/vr/service/isolated_device_provider.cc
@@ -3,13 +3,13 @@ // found in the LICENSE file. #include "chrome/browser/vr/service/isolated_device_provider.h" + +#include "chrome/browser/vr/win/vr_ui_host_impl.h" #include "content/public/common/service_manager_connection.h" #include "device/vr/buildflags/buildflags.h" #include "device/vr/isolated_gamepad_data_fetcher.h" #include "services/service_manager/public/cpp/connector.h" -#include "chrome/browser/vr/win/vr_renderloop_host_win.h" - namespace vr { void IsolatedVRDeviceProvider::Initialize( @@ -49,8 +49,8 @@ device::mojom::VRDisplayInfoPtr display_info) { device::mojom::XRDeviceId id = display_info->id; add_device_callback_.Run(id, display_info.Clone(), std::move(device)); - VRBrowserRendererHostWin::AddCompositor(std::move(display_info), - std::move(compositor_host)); + VRUiHostImpl::AddCompositor(std::move(display_info), + std::move(compositor_host)); registered_devices_.insert(id); device::IsolatedGamepadDataFetcher::Factory::AddGamepad( id, std::move(gamepad_factory)); @@ -59,7 +59,7 @@ void IsolatedVRDeviceProvider::OnDeviceRemoved(device::mojom::XRDeviceId id) { remove_device_callback_.Run(id); registered_devices_.erase(id); - VRBrowserRendererHostWin::RemoveCompositor(id); + VRUiHostImpl::RemoveCompositor(id); device::IsolatedGamepadDataFetcher::Factory::RemoveGamepad(id); } @@ -68,7 +68,7 @@ // should be removed. for (auto id : registered_devices_) { remove_device_callback_.Run(id); - VRBrowserRendererHostWin::RemoveCompositor(id); + VRUiHostImpl::RemoveCompositor(id); device::IsolatedGamepadDataFetcher::Factory::RemoveGamepad(id); } registered_devices_.clear(); @@ -92,7 +92,7 @@ IsolatedVRDeviceProvider::~IsolatedVRDeviceProvider() { for (auto device_id : registered_devices_) { device::IsolatedGamepadDataFetcher::Factory::RemoveGamepad(device_id); - VRBrowserRendererHostWin::RemoveCompositor(device_id); + VRUiHostImpl::RemoveCompositor(device_id); } }
diff --git a/chrome/browser/vr/service/xr_runtime_manager.cc b/chrome/browser/vr/service/xr_runtime_manager.cc index b03bdfc9..4504b7b 100644 --- a/chrome/browser/vr/service/xr_runtime_manager.cc +++ b/chrome/browser/vr/service/xr_runtime_manager.cc
@@ -381,7 +381,7 @@ DCHECK(it != runtimes_.end()); // Remove the device from runtimes_ before notifying services that it was - // removed, since they will query for devices in RemoveRuntime. + // removed, since they will query for devices in RuntimesChanged. std::unique_ptr<BrowserXRRuntime> removed_device = std::move(it->second); runtimes_.erase(it);
diff --git a/chrome/browser/vr/win/vr_renderloop_host_win.cc b/chrome/browser/vr/win/vr_renderloop_host_win.cc deleted file mode 100644 index ad5e7de9..0000000 --- a/chrome/browser/vr/win/vr_renderloop_host_win.cc +++ /dev/null
@@ -1,82 +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/vr/win/vr_renderloop_host_win.h" -#include "chrome/browser/vr/service/browser_xr_runtime.h" -#include "chrome/browser/vr/service/xr_runtime_manager.h" -#include "chrome/browser/vr/win/vr_browser_renderer_thread_win.h" - -namespace vr { - -namespace { -VRBrowserRendererHostWin* g_vr_renderer_host = nullptr; -} - -VRBrowserRendererHostWin::VRBrowserRendererHostWin( - device::mojom::VRDisplayInfoPtr info, - device::mojom::XRCompositorHostPtr compositor) - : compositor_(std::move(compositor)), info_(std::move(info)) { - BrowserXRRuntime* runtime = - XRRuntimeManager::GetInstance()->GetRuntime(info_->id); - if (runtime) { - runtime->AddObserver(this); - } -} - -VRBrowserRendererHostWin::~VRBrowserRendererHostWin() { - // We don't call BrowserXRRuntime::RemoveObserver, because if we are being - // destroyed, it means the corresponding device has been removed from - // XRRuntimeManager, and the BrowserXRRuntime has been destroyed. -} - -void VRBrowserRendererHostWin::SetWebXRWebContents( - content::WebContents* contents) { - // Eventually the contents will be used to poll for permissions, or determine - // what overlays should show. - if (contents) - StartBrowserRenderer(); - else - StopBrowserRenderer(); -} - -void VRBrowserRendererHostWin::SetVRDisplayInfo( - device::mojom::VRDisplayInfoPtr display_info) { - info_ = std::move(display_info); - if (render_thread_) { - render_thread_->SetVRDisplayInfo(info_.Clone()); - } -} - -void VRBrowserRendererHostWin::AddCompositor( - device::mojom::VRDisplayInfoPtr info, - device::mojom::XRCompositorHostPtr compositor) { - // We only expect one device to be enabled at a time. - DCHECK(!g_vr_renderer_host); - g_vr_renderer_host = - new VRBrowserRendererHostWin(std::move(info), std::move(compositor)); -} - -void VRBrowserRendererHostWin::RemoveCompositor(device::mojom::XRDeviceId id) { - DCHECK(g_vr_renderer_host); - g_vr_renderer_host->StopBrowserRenderer(); - delete g_vr_renderer_host; - g_vr_renderer_host = nullptr; -} - -void VRBrowserRendererHostWin::StartBrowserRenderer() { -// Only used for testing currently. To see an example overlay, enable the -// following few lines. -#if 0 - render_thread_ = std::make_unique<VRBrowserRendererThreadWin>(); - render_thread_->Start(); - render_thread_->SetVRDisplayInfo(info_.Clone()); - render_thread_->StartOverlay(compositor_.get()); -#endif -} - -void VRBrowserRendererHostWin::StopBrowserRenderer() { - render_thread_ = nullptr; -} - -} // namespace vr
diff --git a/chrome/browser/vr/win/vr_renderloop_host_win.h b/chrome/browser/vr/win/vr_renderloop_host_win.h deleted file mode 100644 index 56d4f287..0000000 --- a/chrome/browser/vr/win/vr_renderloop_host_win.h +++ /dev/null
@@ -1,47 +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_VR_WIN_VR_RENDERLOOP_HOST_WIN_H_ -#define CHROME_BROWSER_VR_WIN_VR_RENDERLOOP_HOST_WIN_H_ - -#include "base/threading/thread.h" -#include "chrome/browser/vr/service/browser_xr_runtime.h" -#include "content/public/browser/web_contents.h" -#include "device/vr/public/mojom/isolated_xr_service.mojom.h" -#include "device/vr/public/mojom/vr_service.mojom.h" - -namespace vr { - -class VRBrowserRendererThreadWin; - -class VRBrowserRendererHostWin : public BrowserXRRuntimeObserver { - public: - // Called by IsolatedDeviceProvider when devices are added/removed. These - // manage the lifetime of VRBrowserRendererHostWin instances. - static void AddCompositor(device::mojom::VRDisplayInfoPtr info, - device::mojom::XRCompositorHostPtr compositor); - static void RemoveCompositor(device::mojom::XRDeviceId id); - - private: - VRBrowserRendererHostWin(device::mojom::VRDisplayInfoPtr info, - device::mojom::XRCompositorHostPtr compositor); - ~VRBrowserRendererHostWin() override; - - // Called by BrowserXRRuntime (we register to observe a BrowserXRDevice). - // The parameter contents indicate which page is rendering with WebXR or WebVR - // presentation. When null, no page is presenting. - void SetWebXRWebContents(content::WebContents* contents) override; - void SetVRDisplayInfo(device::mojom::VRDisplayInfoPtr display_info) override; - - void StartBrowserRenderer(); - void StopBrowserRenderer(); - - device::mojom::XRCompositorHostPtr compositor_; - std::unique_ptr<VRBrowserRendererThreadWin> render_thread_; - device::mojom::VRDisplayInfoPtr info_; -}; - -} // namespace vr - -#endif // CHROME_BROWSER_VR_WIN_VR_RENDERLOOP_HOST_WIN_H_
diff --git a/chrome/browser/vr/win/vr_ui_host_impl.cc b/chrome/browser/vr/win/vr_ui_host_impl.cc new file mode 100644 index 0000000..11c33a8 --- /dev/null +++ b/chrome/browser/vr/win/vr_ui_host_impl.cc
@@ -0,0 +1,79 @@ +// 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/vr/win/vr_ui_host_impl.h" +#include "chrome/browser/vr/service/browser_xr_runtime.h" +#include "chrome/browser/vr/service/xr_runtime_manager.h" +#include "chrome/browser/vr/win/vr_browser_renderer_thread_win.h" + +namespace vr { + +namespace { +VRUiHostImpl* g_vr_ui_host = nullptr; +} + +VRUiHostImpl::VRUiHostImpl(device::mojom::VRDisplayInfoPtr info, + device::mojom::XRCompositorHostPtr compositor) + : compositor_(std::move(compositor)), info_(std::move(info)) { + BrowserXRRuntime* runtime = + XRRuntimeManager::GetInstance()->GetRuntime(info_->id); + if (runtime) { + runtime->AddObserver(this); + } +} + +VRUiHostImpl::~VRUiHostImpl() { + // We don't call BrowserXRRuntime::RemoveObserver, because if we are being + // destroyed, it means the corresponding device has been removed from + // XRRuntimeManager, and the BrowserXRRuntime has been destroyed. +} + +void VRUiHostImpl::SetWebXRWebContents(content::WebContents* contents) { + // Eventually the contents will be used to poll for permissions, or determine + // what overlays should show. + if (contents) + StartUiRendering(); + else + StopUiRendering(); +} + +void VRUiHostImpl::SetVRDisplayInfo( + device::mojom::VRDisplayInfoPtr display_info) { + info_ = std::move(display_info); + if (ui_rendering_thread_) { + ui_rendering_thread_->SetVRDisplayInfo(info_.Clone()); + } +} + +void VRUiHostImpl::AddCompositor( + device::mojom::VRDisplayInfoPtr info, + device::mojom::XRCompositorHostPtr compositor) { + // We only expect one device to be enabled at a time. + DCHECK(!g_vr_ui_host); + g_vr_ui_host = new VRUiHostImpl(std::move(info), std::move(compositor)); +} + +void VRUiHostImpl::RemoveCompositor(device::mojom::XRDeviceId id) { + DCHECK(g_vr_ui_host); + g_vr_ui_host->StopUiRendering(); + delete g_vr_ui_host; + g_vr_ui_host = nullptr; +} + +void VRUiHostImpl::StartUiRendering() { +// Only used for testing currently. To see an example overlay, enable the +// following few lines. +#if 0 + ui_rendering_thread_ = std::make_unique<VRBrowserRendererThreadWin>(); + ui_rendering_thread_->Start(); + ui_rendering_thread_->SetVRDisplayInfo(info_.Clone()); + ui_rendering_thread_->StartOverlay(compositor_.get()); +#endif +} + +void VRUiHostImpl::StopUiRendering() { + ui_rendering_thread_ = nullptr; +} + +} // namespace vr
diff --git a/chrome/browser/vr/win/vr_ui_host_impl.h b/chrome/browser/vr/win/vr_ui_host_impl.h new file mode 100644 index 0000000..2973635 --- /dev/null +++ b/chrome/browser/vr/win/vr_ui_host_impl.h
@@ -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. + +#ifndef CHROME_BROWSER_VR_WIN_VR_UI_HOST_IMPL_H_ +#define CHROME_BROWSER_VR_WIN_VR_UI_HOST_IMPL_H_ + +#include "base/threading/thread.h" +#include "chrome/browser/vr/service/browser_xr_runtime.h" +#include "content/public/browser/web_contents.h" +#include "device/vr/public/mojom/isolated_xr_service.mojom.h" +#include "device/vr/public/mojom/vr_service.mojom.h" + +namespace vr { + +class VRBrowserRendererThreadWin; + +class VRUiHostImpl : public BrowserXRRuntimeObserver { + public: + // Called by IsolatedDeviceProvider when devices are added/removed. These + // manage the lifetime of VRBrowserRendererHostWin instances. + static void AddCompositor(device::mojom::VRDisplayInfoPtr info, + device::mojom::XRCompositorHostPtr compositor); + static void RemoveCompositor(device::mojom::XRDeviceId id); + + private: + VRUiHostImpl(device::mojom::VRDisplayInfoPtr info, + device::mojom::XRCompositorHostPtr compositor); + ~VRUiHostImpl() override; + + // BrowserXRRuntimeObserver implementation. + void SetWebXRWebContents(content::WebContents* contents) override; + void SetVRDisplayInfo(device::mojom::VRDisplayInfoPtr display_info) override; + + // Internal methods used to start/stop the UI rendering thread that is used + // for drawing browser UI (such as permission prompts) for display in VR. + void StartUiRendering(); + void StopUiRendering(); + + device::mojom::XRCompositorHostPtr compositor_; + std::unique_ptr<VRBrowserRendererThreadWin> ui_rendering_thread_; + device::mojom::VRDisplayInfoPtr info_; +}; + +} // namespace vr + +#endif // CHROME_BROWSER_VR_WIN_VR_UI_HOST_IMPL_H_
diff --git a/chrome/browser/web_applications/components/web_app_shortcut_mac.h b/chrome/browser/web_applications/components/web_app_shortcut_mac.h index c200ea86..da3183ce 100644 --- a/chrome/browser/web_applications/components/web_app_shortcut_mac.h +++ b/chrome/browser/web_applications/components/web_app_shortcut_mac.h
@@ -25,17 +25,22 @@ namespace web_app { -// Callback type for MaybeLaunchShortcut. If |shim_process| is valid then the +enum class LaunchShimUpdateBehavior { + NO_UPDATE, + UPDATE_IF_INSTALLED, + RECREATE, +}; + +// Callback type for LaunchShim. If |shim_process| is valid then the // app shim was launched. -using LaunchAppCallback = base::OnceCallback<void(base::Process shim_process)>; +using LaunchShimCallback = base::OnceCallback<void(base::Process shim_process)>; -// If necessary, launch the shortcut for an app. Return the process that was -// launched. -void MaybeLaunchShortcut(std::unique_ptr<ShortcutInfo> shortcut_info, - LaunchAppCallback callback); - -// Update the shortcut and launch it. -void UpdateAndLaunchShim(std::unique_ptr<web_app::ShortcutInfo> shortcut_info); +// Launch the shim specified by |shortcut_info|. Update the shim prior to launch +// if requested. Return in |callback| the pid that was launched (or an invalid +// pid if none was launched). +void LaunchShim(LaunchShimUpdateBehavior update_behavior, + LaunchShimCallback callback, + std::unique_ptr<web_app::ShortcutInfo> shortcut_info); std::unique_ptr<web_app::ShortcutInfo> RecordAppShimErrorAndBuildShortcutInfo( const base::FilePath& bundle_path); @@ -78,7 +83,13 @@ bool CreateShortcuts(ShortcutCreationReason creation_reason, ShortcutLocations creation_locations); void DeleteShortcuts(); - bool UpdateShortcuts(); + + // Recreate the shortcuts where they are found on disk and in the profile + // path. If |recreate_if_needed| is true, then recreate the shortcuts if no + // matching shortcuts are found on disk. Populate |updated_paths| with the + // paths that were updated. + bool UpdateShortcuts(bool recreate_if_needed, + std::vector<base::FilePath>* updated_paths); // Show the bundle we just generated in the Finder. virtual void RevealAppShimInFinder() const; @@ -103,9 +114,11 @@ // relevant information. bool BuildShortcut(const base::FilePath& staging_path) const; - // Builds a shortcut and copies it into the given destination folders. - // Returns with the number of successful copies. Returns on the first failure. - size_t CreateShortcutsIn(const std::vector<base::FilePath>& folders) const; + // Builds a shortcut and copies it to the specified app paths. Returns with + // the number of successful copies created. If non-nullptr, populates + // |updated_paths| with the paths that were successfully updated. + size_t CreateShortcutsAt(const std::vector<base::FilePath>& app_paths, + std::vector<base::FilePath>* updated_paths) const; // Updates the InfoPlist.string inside |app_path| with the display name for // the app.
diff --git a/chrome/browser/web_applications/components/web_app_shortcut_mac.mm b/chrome/browser/web_applications/components/web_app_shortcut_mac.mm index aeb06ee..50e0397d 100644 --- a/chrome/browser/web_applications/components/web_app_shortcut_mac.mm +++ b/chrome/browser/web_applications/components/web_app_shortcut_mac.mm
@@ -183,40 +183,64 @@ user_data_dir.value(), base::CompareCase::SENSITIVE); } -void LaunchShimOnFileThread(web_app::LaunchAppCallback callback, - bool launched_after_rebuild, +void LaunchShimOnFileThread(web_app::LaunchShimUpdateBehavior update_behavior, + web_app::LaunchShimCallback callback, const web_app::ShortcutInfo& shortcut_info) { base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK); web_app::WebAppShortcutCreator shortcut_creator( web_app::internals::GetShortcutDataDir(shortcut_info), &shortcut_info); - // Attempt to locate the shim's path using LaunchServices. - std::vector<base::FilePath> shim_paths = shortcut_creator.GetAppBundlesById(); - - // Add as a last resort the copy in the web app's |app_data_dir_|, in case - // the user deleted all other copies. - shim_paths.push_back(shortcut_creator.GetInternalShortcutPath()); - base::FilePath shim_path = shim_paths.front(); - if (!base::PathExists(shim_path)) { - base::PostTaskWithTraits( - FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(std::move(callback), base::Process())); - return; + // Recreate shims if requested, and populate |shim_paths| with the paths to + // attempt to launch. + bool launched_after_rebuild = false; + std::vector<base::FilePath> shim_paths; + switch (update_behavior) { + case web_app::LaunchShimUpdateBehavior::NO_UPDATE: + // Attempt to locate the shim's path using LaunchServices, and as a last + // resort use the copy in the web app's |app_data_dir_|, in case the user + // deleted all other copies. + shim_paths = shortcut_creator.GetAppBundlesById(); + shim_paths.push_back(shortcut_creator.GetInternalShortcutPath()); + break; + case web_app::LaunchShimUpdateBehavior::UPDATE_IF_INSTALLED: + // Only attempt to launch shims that were updated. + launched_after_rebuild = true; + shortcut_creator.UpdateShortcuts(false, &shim_paths); + break; + case web_app::LaunchShimUpdateBehavior::RECREATE: + // Likewise, only attempt to launch shims that were updated. + launched_after_rebuild = true; + shortcut_creator.UpdateShortcuts(true, &shim_paths); + break; } - base::CommandLine command_line(base::CommandLine::NO_PROGRAM); - command_line.AppendSwitchASCII(app_mode::kLaunchedByChromeProcessId, - base::IntToString(base::GetCurrentProcId())); - if (launched_after_rebuild) - command_line.AppendSwitch(app_mode::kLaunchedAfterRebuild); - // Launch without activating (NSWorkspaceLaunchWithoutActivation). - base::Process process = base::mac::OpenApplicationWithPath( - shim_path, command_line, - NSWorkspaceLaunchDefault | NSWorkspaceLaunchWithoutActivation); + // Attempt to launch the shim. + for (const auto& shim_path : shim_paths) { + if (!base::PathExists(shim_path)) + continue; + + base::CommandLine command_line(base::CommandLine::NO_PROGRAM); + command_line.AppendSwitchASCII(app_mode::kLaunchedByChromeProcessId, + base::IntToString(base::GetCurrentProcId())); + if (launched_after_rebuild) + command_line.AppendSwitch(app_mode::kLaunchedAfterRebuild); + + // Launch without activating (NSWorkspaceLaunchWithoutActivation). + base::Process process = base::mac::OpenApplicationWithPath( + shim_path, command_line, + NSWorkspaceLaunchDefault | NSWorkspaceLaunchWithoutActivation); + if (process.IsValid()) { + base::PostTaskWithTraits( + FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(std::move(callback), std::move(process))); + return; + } + } + base::PostTaskWithTraits( FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(std::move(callback), std::move(process))); + base::BindOnce(std::move(callback), base::Process())); } base::FilePath GetAppLoaderPath() { @@ -224,29 +248,6 @@ base::mac::NSToCFCast(@"app_mode_loader.app")); } -void UpdatePlatformShortcutsInternal( - const base::FilePath& app_data_path, - const base::string16& old_app_title, - const web_app::ShortcutInfo& shortcut_info) { - base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK); - if (web_app::AppShimLaunchDisabled()) - return; - - web_app::WebAppShortcutCreator shortcut_creator(app_data_path, - &shortcut_info); - shortcut_creator.UpdateShortcuts(); -} - -void UpdateAndLaunchShimOnFileThread( - const web_app::ShortcutInfo& shortcut_info) { - base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK); - base::FilePath shortcut_data_dir = web_app::GetWebAppDataDirectory( - shortcut_info.profile_path, shortcut_info.extension_id, GURL()); - UpdatePlatformShortcutsInternal(shortcut_data_dir, base::string16(), - shortcut_info); - LaunchShimOnFileThread(base::DoNothing(), true, shortcut_info); -} - base::FilePath GetLocalizableAppShortcutsSubdirName() { static const char kChromiumAppDirName[] = "Chromium Apps.localized"; static const char kChromeAppDirName[] = "Chrome Apps.localized"; @@ -483,12 +484,6 @@ namespace web_app { -void UpdateAndLaunchShim(std::unique_ptr<web_app::ShortcutInfo> shortcut_info) { - web_app::internals::PostShortcutIOTask( - base::BindOnce(&UpdateAndLaunchShimOnFileThread), - std::move(shortcut_info)); -} - std::unique_ptr<web_app::ShortcutInfo> RecordAppShimErrorAndBuildShortcutInfo( const base::FilePath& bundle_path) { NSDictionary* plist = ReadPlist(GetPlistPath(bundle_path)); @@ -558,42 +553,48 @@ UpdateIcon(staging_path); } -size_t WebAppShortcutCreator::CreateShortcutsIn( - const std::vector<base::FilePath>& folders) const { +size_t WebAppShortcutCreator::CreateShortcutsAt( + const std::vector<base::FilePath>& dst_app_paths, + std::vector<base::FilePath>* updated_paths) const { + DCHECK(updated_paths && updated_paths->empty()); size_t succeeded = 0; base::ScopedTempDir scoped_temp_dir; if (!scoped_temp_dir.CreateUniqueTempDir()) return 0; - base::FilePath app_name = GetShortcutBasename(); - base::FilePath staging_path = scoped_temp_dir.GetPath().Append(app_name); + // Create the bundle in staging_path. + base::FilePath staging_path = + scoped_temp_dir.GetPath().Append(GetShortcutBasename()); if (!BuildShortcut(staging_path)) return 0; - for (std::vector<base::FilePath>::const_iterator it = folders.begin(); - it != folders.end(); ++it) { - const base::FilePath& dst_path = *it; - if (!base::CreateDirectory(dst_path)) { - LOG(ERROR) << "Creating directory " << dst_path.value() << " failed."; - return succeeded; + // Copy to each destination in |dst_app_paths|. + for (const auto& dst_app_path : dst_app_paths) { + // Create the parent directory for the app. + base::FilePath dst_parent_dir = dst_app_path.DirName(); + if (!base::CreateDirectory(dst_parent_dir)) { + LOG(ERROR) << "Creating directory " << dst_parent_dir.value() + << " failed."; + continue; } - // Ensure the copy does not merge with stale info. - base::DeleteFile(dst_path.Append(app_name), true); + // Delete any old copies that may exist. + base::DeleteFile(dst_app_path, true); - if (!base::CopyDirectory(staging_path, dst_path, true)) { - LOG(ERROR) << "Copying app to dst path: " << dst_path.value() + // Copy the bundle to |dst_app_path|. + if (!base::CopyDirectory(staging_path, dst_app_path, true)) { + LOG(ERROR) << "Copying app to dst dir: " << dst_parent_dir.value() << " failed"; - return succeeded; + continue; } // Remove the quarantine attribute from both the bundle and the executable. - base::mac::RemoveQuarantineAttribute(dst_path.Append(app_name)); - base::mac::RemoveQuarantineAttribute(dst_path.Append(app_name) - .Append("Contents") + base::mac::RemoveQuarantineAttribute(dst_app_path); + base::mac::RemoveQuarantineAttribute(dst_app_path.Append("Contents") .Append("MacOS") .Append("app_mode_loader")); + updated_paths->push_back(dst_app_path); ++succeeded; } @@ -619,7 +620,7 @@ // If non-nil, this path is added to the OSX Dock after creating shortcuts. NSString* path_to_add_to_dock = nil; - std::vector<base::FilePath> paths; + std::vector<base::FilePath> app_paths; // The app list shim is not tied to a particular profile, so omit the copy // placed under the profile path. For shims, this copy is used when the @@ -630,23 +631,24 @@ path_to_add_to_dock = base::SysUTF8ToNSString( applications_dir.Append(GetShortcutBasename()).AsUTF8Unsafe()); } else { - paths.push_back(app_data_dir_); + app_paths.push_back(GetInternalShortcutPath()); } bool shortcut_visible = creation_locations.applications_menu_location != APP_MENU_LOCATION_HIDDEN; if (shortcut_visible) - paths.push_back(applications_dir); + app_paths.push_back(GetApplicationsShortcutPath()); - DCHECK(!paths.empty()); - size_t success_count = CreateShortcutsIn(paths); + DCHECK(!app_paths.empty()); + std::vector<base::FilePath> updated_app_paths; + size_t success_count = CreateShortcutsAt(app_paths, &updated_app_paths); if (success_count == 0) return false; if (!is_app_list) UpdateInternalBundleIdentifier(); - if (success_count != paths.size()) + if (success_count != app_paths.size()) return false; if (creation_locations.in_quick_launch_bar && path_to_add_to_dock && @@ -693,18 +695,10 @@ base::DeleteFile(app_data_dir_, false); } -bool WebAppShortcutCreator::UpdateShortcuts() { - std::vector<base::FilePath> paths; - paths.push_back(app_data_dir_); - - // Remember whether the copy in the profile directory exists. If it doesn't - // and others do, it should be re-created. Otherwise, it's a signal that a - // shortcut has never been created. - bool profile_copy_exists = base::PathExists(GetInternalShortcutPath()); - - // Try to update the copy under ~/Applications. If that does not exist, check - // if a matching bundle can be found elsewhere. - base::FilePath app_path = GetApplicationsShortcutPath(); +bool WebAppShortcutCreator::UpdateShortcuts( + bool recreate_if_needed, + std::vector<base::FilePath>* updated_paths) { + DCHECK(updated_paths && updated_paths->empty()); // Never look in ~/Applications or search the system for a bundle ID in a test // since that relies on global system state and potentially cruft that may be @@ -712,26 +706,32 @@ // TODO(tapted): Remove this check when tests that arrive here via setting // |g_app_shims_allow_update_and_launch_in_tests| can properly mock out all // the calls below. + std::vector<base::FilePath> app_paths; if (!g_app_shims_allow_update_and_launch_in_tests) { - if (app_path.empty() || !base::PathExists(app_path)) { - auto app_paths = GetAppBundlesById(); - if (!app_paths.empty()) - app_path = app_paths.front(); - else - app_path = base::FilePath(); - } + // Update all copies located by bundle id (wherever it was moved or copied + // by the user). + app_paths = GetAppBundlesById(); - if (app_path.empty()) { - if (profile_copy_exists && info_->from_bookmark) { + // If that path does not exist, consider creating a new entry in + // ~/Applications. + if (app_paths.empty()) { + // Check to see if there exists a copy in the profile directory. If one + // doesn't, but other shortcuts do exist, it should be re-created. + // Otherwise, take its absence as a signal that a shortcut has never been + // created. + bool profile_copy_exists = base::PathExists(GetInternalShortcutPath()); + if (recreate_if_needed || (profile_copy_exists && info_->from_bookmark)) { // The bookmark app shortcut has been deleted by the user. Restore it, // as the Mac UI for bookmark apps creates the expectation that the app // will be added to Applications. - app_path = GetApplicationsDirname(); - paths.push_back(app_path); + app_paths.push_back(GetApplicationsShortcutPath()); } - } else { - paths.push_back(app_path.DirName()); } + // Update or create the copy under the profile directory only if there are + // other paths being updated. + if (app_paths.empty()) + return false; + app_paths.push_back(GetInternalShortcutPath()); } else { // If a test has set g_app_shims_allow_update_and_launch_in_tests, it means // it relies on UpdateShortcuts() to create shortcuts. (Tests can't rely on @@ -739,23 +739,13 @@ // the UI thread). So, allow shortcuts to be created for this case, even if // none currently exist. TODO(tapted): Remove this when tests are properly // mocked. - profile_copy_exists = true; + app_paths.push_back(GetInternalShortcutPath()); } - // When upgrading, if no shim exists anywhere on disk, don't create the copy - // under the profile directory for the first time. The best way to tell - // whether a shortcut has been created is to poke around on disk, so the - // upgrade process must send all candidate extensions to the FILE thread. - // Then those without shortcuts will get culled here. - if (paths.size() == 1 && !profile_copy_exists) - return false; - - size_t success_count = CreateShortcutsIn(paths); - if (success_count == 0) - return false; - - UpdateInternalBundleIdentifier(); - return success_count == paths.size() && !app_path.empty(); + size_t success_count = CreateShortcutsAt(app_paths, updated_paths); + if (success_count) + UpdateInternalBundleIdentifier(); + return success_count == app_paths.size(); } base::FilePath WebAppShortcutCreator::GetApplicationsDirname() const { @@ -989,8 +979,9 @@ openFile:base::mac::FilePathToNSString(apps_path)]; } -void MaybeLaunchShortcut(std::unique_ptr<ShortcutInfo> shortcut_info, - LaunchAppCallback callback) { +void LaunchShim(LaunchShimUpdateBehavior update_behavior, + LaunchShimCallback callback, + std::unique_ptr<web_app::ShortcutInfo> shortcut_info) { if (web_app::AppShimLaunchDisabled()) { base::PostTaskWithTraits( FROM_HERE, {content::BrowserThread::UI}, @@ -999,7 +990,8 @@ } web_app::internals::PostShortcutIOTask( - base::BindOnce(&LaunchShimOnFileThread, std::move(callback), false), + base::BindOnce(&LaunchShimOnFileThread, update_behavior, + std::move(callback)), std::move(shortcut_info)); } @@ -1027,7 +1019,14 @@ void UpdatePlatformShortcuts(const base::FilePath& app_data_path, const base::string16& old_app_title, const ShortcutInfo& shortcut_info) { - UpdatePlatformShortcutsInternal(app_data_path, old_app_title, shortcut_info); + base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK); + if (web_app::AppShimLaunchDisabled()) + return; + + web_app::WebAppShortcutCreator shortcut_creator(app_data_path, + &shortcut_info); + std::vector<base::FilePath> updated_shim_paths; + shortcut_creator.UpdateShortcuts(false, &updated_shim_paths); } void DeleteAllShortcutsForProfile(const base::FilePath& profile_path) {
diff --git a/chrome/browser/web_applications/components/web_app_shortcut_mac_unittest.mm b/chrome/browser/web_applications/components/web_app_shortcut_mac_unittest.mm index 5296fe3e..b66a54c5 100644 --- a/chrome/browser/web_applications/components/web_app_shortcut_mac_unittest.mm +++ b/chrome/browser/web_applications/components/web_app_shortcut_mac_unittest.mm
@@ -203,10 +203,17 @@ EXPECT_TRUE(base::DeleteFile(other_shim_path.Append("Contents"), true)); - EXPECT_TRUE(shortcut_creator.UpdateShortcuts()); + std::vector<base::FilePath> updated_paths; + EXPECT_TRUE(shortcut_creator.UpdateShortcuts(false, &updated_paths)); EXPECT_FALSE(base::PathExists(shim_path_)); EXPECT_TRUE(base::PathExists(other_shim_path.Append("Contents"))); + // The list of updated paths is the paths found by bundle, plus the internal + // path. + EXPECT_EQ(bundle_by_id_paths.size() + 1, updated_paths.size()); + updated_paths.pop_back(); + EXPECT_EQ(bundle_by_id_paths, updated_paths); + // Also test case where GetAppBundlesByIdUnsorted fails. bundle_by_id_paths.clear(); EXPECT_CALL(shortcut_creator, GetAppBundlesByIdUnsorted()) @@ -216,9 +223,25 @@ EXPECT_TRUE(base::DeleteFile(other_shim_path.Append("Contents"), true)); - EXPECT_FALSE(shortcut_creator.UpdateShortcuts()); + updated_paths.clear(); + EXPECT_FALSE(shortcut_creator.UpdateShortcuts(false, &updated_paths)); + EXPECT_TRUE(updated_paths.empty()); EXPECT_FALSE(base::PathExists(shim_path_)); EXPECT_FALSE(base::PathExists(other_shim_path.Append("Contents"))); + + // Also test case where GetAppBundlesByIdUnsorted fails and recreation is + // forced. + bundle_by_id_paths.clear(); + EXPECT_CALL(shortcut_creator, GetAppBundlesByIdUnsorted()) + .WillOnce(Return(bundle_by_id_paths)); + + // The default shim path is created along with the internal path. + updated_paths.clear(); + EXPECT_TRUE(shortcut_creator.UpdateShortcuts(true, &updated_paths)); + EXPECT_EQ(2u, updated_paths.size()); + EXPECT_EQ(shim_path_, updated_paths[0]); + EXPECT_TRUE(base::PathExists(shim_path_)); + EXPECT_FALSE(base::PathExists(other_shim_path.Append("Contents"))); } TEST_F(WebAppShortcutCreatorTest, UpdateBookmarkAppShortcut) { @@ -246,7 +269,8 @@ EXPECT_TRUE(base::DeleteFile(other_shim_path, true)); // The original shim should be recreated. - EXPECT_TRUE(shortcut_creator.UpdateShortcuts()); + std::vector<base::FilePath> updated_paths; + EXPECT_TRUE(shortcut_creator.UpdateShortcuts(false, &updated_paths)); EXPECT_TRUE(base::PathExists(shim_path_)); EXPECT_FALSE(base::PathExists(other_shim_path.Append("Contents"))); }
diff --git a/chrome/browser/web_applications/extensions/web_app_extension_shortcut_mac.mm b/chrome/browser/web_applications/extensions/web_app_extension_shortcut_mac.mm index 6564dd9..f555819 100644 --- a/chrome/browser/web_applications/extensions/web_app_extension_shortcut_mac.mm +++ b/chrome/browser/web_applications/extensions/web_app_extension_shortcut_mac.mm
@@ -4,6 +4,8 @@ #include "chrome/browser/web_applications/extensions/web_app_extension_shortcut_mac.h" +#include "base/bind.h" +#include "base/bind_helpers.h" #include "base/task/post_task.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" @@ -88,9 +90,11 @@ shortcut_info->extension_id, extensions::ExtensionRegistry::ENABLED); if (!extension || !extension->is_platform_app()) return; - - web_app::GetShortcutInfoForApp(extension, profile, - base::BindOnce(&UpdateAndLaunchShim)); + base::OnceCallback<void(base::Process)> launch_callback = base::DoNothing(); + web_app::GetShortcutInfoForApp( + extension, profile, + base::BindOnce(&LaunchShim, LaunchShimUpdateBehavior::UPDATE_IF_INSTALLED, + std::move(launch_callback))); } bool MaybeRebuildShortcut(const base::CommandLine& command_line) {
diff --git a/chrome/credential_provider/gaiacp/dllmain.cc b/chrome/credential_provider/gaiacp/dllmain.cc index 2971250..0728b17 100644 --- a/chrome/credential_provider/gaiacp/dllmain.cc +++ b/chrome/credential_provider/gaiacp/dllmain.cc
@@ -66,6 +66,13 @@ // Returns a class factory to create an object of the requested type. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { + // Check to see if the credential provider has crashed too much recently. + // If it has then do not allow it to create any credential providers. + if (!credential_provider::VerifyStartupSentinel()) { + LOGFN(ERROR) << "Disabled due to previous unsuccessful starts"; + return E_NOTIMPL; + } + return _AtlModule.DllGetClassObject(rclsid, riid, ppv); }
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base.cc b/chrome/credential_provider/gaiacp/gaia_credential_base.cc index 419029b..c7a383d 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_base.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_base.cc
@@ -771,12 +771,23 @@ HRESULT CGaiaCredentialBase::UnAdvise(void) { LOGFN(INFO); events_.Release(); + + // The unadvise should only occur after the user has logged in, so if they + // never selected any gaia credential and just used normal credentials this + // function will be called in that situation and it is guaranteed that the + // user has at least been able provide some input to winlogon. + DeleteStartupSentinel(); + return S_OK; } HRESULT CGaiaCredentialBase::SetSelected(BOOL* auto_login) { *auto_login = AreCredentialsValid(); LOGFN(INFO) << "auto-login=" << *auto_login; + + // After this point the user is able to interact with the winlogon and thus + // can avoid potential crash loops so the startup sentinel can be deleted. + DeleteStartupSentinel(); return S_OK; }
diff --git a/chrome/credential_provider/gaiacp/gcp_utils.cc b/chrome/credential_provider/gaiacp/gcp_utils.cc index 94ba384..ed4d062f 100644 --- a/chrome/credential_provider/gaiacp/gcp_utils.cc +++ b/chrome/credential_provider/gaiacp/gcp_utils.cc
@@ -44,6 +44,7 @@ #include "base/win/embedded_i18n/language_Selector.h" #include "base/win/registry.h" #include "base/win/win_util.h" +#include "chrome/common/chrome_version.h" #include "chrome/credential_provider/common/gcp_strings.h" #include "chrome/credential_provider/gaiacp/gaia_resources.h" #include "chrome/credential_provider/gaiacp/logging.h" @@ -52,6 +53,11 @@ namespace { +constexpr char kSentinelFilename[] = "gcpw_startup.sentinel"; +constexpr base::FilePath::CharType kCredentialProviderFolder[] = + L"Credential Provider"; +constexpr int64_t kMaxConsecutiveCrashCount = 5; + constexpr base::win::i18n::LanguageSelector::LangToOffset kLanguageOffsetPairs[] = { #define HANDLE_LANGUAGE(l_, o_) {L## #l_, o_}, @@ -59,6 +65,21 @@ #undef HANDLE_LANGUAGE }; +base::FilePath GetStartupSentinelLocation() { + base::FilePath sentienal_path; + if (!base::PathService::Get(base::DIR_COMMON_APP_DATA, &sentienal_path)) { + HRESULT hr = HRESULT_FROM_WIN32(::GetLastError()); + LOGFN(ERROR) << "PathService::Get(DIR_COMMON_APP_DATA) hr=" << putHR(hr); + return base::FilePath(); + } + + sentienal_path = sentienal_path.Append(GetInstallParentDirectoryName()) + .Append(kCredentialProviderFolder); + + return sentienal_path.Append(TEXT(CHROME_VERSION_STRING)) + .AppendASCII(kSentinelFilename); +} + const base::win::i18n::LanguageSelector& GetLanguageSelector() { static base::NoDestructor<base::win::i18n::LanguageSelector> instance( base::string16(), &kLanguageOffsetPairs[0], @@ -156,7 +177,7 @@ } dest_path = dest_path.Append(GetInstallParentDirectoryName()) - .Append(FILE_PATH_LITERAL("Credential Provider")); + .Append(kCredentialProviderFolder); return dest_path; } @@ -738,6 +759,49 @@ return hr; } +bool VerifyStartupSentinel() { + // Always try to write to the startup sentinel file. If writing or opening + // fails for any reason (file locked, no access etc) consider this a failure. + // If no sentinel file path can be found this probably means that we are + // running in a unit test so just let the verification pass in this case. + base::FilePath startup_sentinel_path = GetStartupSentinelLocation(); + if (!startup_sentinel_path.empty()) { + base::FilePath startup_sentinel_directory = startup_sentinel_path.DirName(); + if (!base::DirectoryExists(startup_sentinel_directory)) { + base::File::Error error; + if (!base::CreateDirectoryAndGetError(startup_sentinel_directory, + &error)) { + LOGFN(ERROR) << "Could not create sentinel directory='" + << startup_sentinel_directory << "' error=" << error; + return false; + } + } + base::File startup_sentinel( + startup_sentinel_path, + base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_APPEND); + + // Keep writing to the sentinel file until we have reached + // |kMaxConsecutiveCrashCount| at which point it is assumed that GCPW + // is crashing continuously and should be disabled. + if (!startup_sentinel.IsValid() || + startup_sentinel.GetLength() >= kMaxConsecutiveCrashCount) { + return false; + } + + return startup_sentinel.WriteAtCurrentPos("0", 1) == 1; + } + + return true; +} + +void DeleteStartupSentinel() { + base::FilePath startup_sentinel_path = GetStartupSentinelLocation(); + if (base::PathExists(startup_sentinel_path) && + !base::DeleteFile(startup_sentinel_path, false)) { + LOGFN(ERROR) << "Failed to delete sentinel file: " << startup_sentinel_path; + } +} + base::string16 GetStringResource(int base_message_id) { base::string16 localized_string;
diff --git a/chrome/credential_provider/gaiacp/gcp_utils.h b/chrome/credential_provider/gaiacp/gcp_utils.h index 94c295f..d008836b 100644 --- a/chrome/credential_provider/gaiacp/gcp_utils.h +++ b/chrome/credential_provider/gaiacp/gcp_utils.h
@@ -196,6 +196,12 @@ // Gets the auth package id for NEGOSSP_NAME_A. HRESULT GetAuthenticationPackageId(ULONG* id); +// Handles the writing and deletion of a startup sentinel file used to ensure +// that the GCPW does not crash continuously on startup and render the +// winlogon process unusable. +bool VerifyStartupSentinel(); +void DeleteStartupSentinel(); + // Gets a string resource from the DLL with the given id. base::string16 GetStringResource(int base_message_id);
diff --git a/chrome/installer/util/l10n_string_util.cc b/chrome/installer/util/l10n_string_util.cc index 8494422f3..87e0b07 100644 --- a/chrome/installer/util/l10n_string_util.cc +++ b/chrome/installer/util/l10n_string_util.cc
@@ -20,7 +20,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/win/atl.h" -#include "base/win/embedded_i18n/language_Selector.h" +#include "base/win/embedded_i18n/language_selector.h" #include "chrome/install_static/install_details.h" #include "chrome/install_static/install_modes.h" #include "chrome/installer/util/google_update_settings.h"
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 2b0d1f799..3b6a46d25 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -1162,58 +1162,39 @@ void ChromeContentRendererClient::PrepareErrorPage( content::RenderFrame* render_frame, - const WebURLRequest& failed_request, const blink::WebURLError& web_error, + const std::string& http_method, + bool ignoring_cache, std::string* error_html) { - PrepareErrorPageInternal( - render_frame, failed_request, - error_page::Error::NetError(web_error.url(), web_error.reason(), - web_error.has_copy_in_cache()), - error_html); + NetErrorHelper::Get(render_frame) + ->PrepareErrorPage( + error_page::Error::NetError(web_error.url(), web_error.reason(), + web_error.has_copy_in_cache()), + http_method == "POST", ignoring_cache, error_html); } void ChromeContentRendererClient::PrepareErrorPageForHttpStatusError( content::RenderFrame* render_frame, - const WebURLRequest& failed_request, const GURL& unreachable_url, + const std::string& http_method, + bool ignoring_cache, int http_status, std::string* error_html) { - PrepareErrorPageInternal( - render_frame, failed_request, - error_page::Error::HttpError(unreachable_url, http_status), error_html); + NetErrorHelper::Get(render_frame) + ->PrepareErrorPage( + error_page::Error::HttpError(unreachable_url, http_status), + http_method == "POST", ignoring_cache, error_html); } void ChromeContentRendererClient::GetErrorDescription( - const blink::WebURLRequest& failed_request, - const blink::WebURLError& error, + const blink::WebURLError& web_error, + const std::string& http_method, base::string16* error_description) { - GetErrorDescriptionInternal( - failed_request, - error_page::Error::NetError(error.url(), error.reason(), - error.has_copy_in_cache()), - error_description); -} - -void ChromeContentRendererClient::PrepareErrorPageInternal( - content::RenderFrame* render_frame, - const WebURLRequest& failed_request, - const error_page::Error& error, - std::string* error_html) { - bool is_post = failed_request.HttpMethod().Ascii() == "POST"; - bool is_ignoring_cache = - failed_request.GetCacheMode() == FetchCacheMode::kBypassCache; - NetErrorHelper::Get(render_frame) - ->PrepareErrorPage(error, is_post, is_ignoring_cache, error_html); -} - -void ChromeContentRendererClient::GetErrorDescriptionInternal( - const blink::WebURLRequest& failed_request, - const error_page::Error& error, - base::string16* error_description) { - bool is_post = failed_request.HttpMethod().Ascii() == "POST"; + error_page::Error error = error_page::Error::NetError( + web_error.url(), web_error.reason(), web_error.has_copy_in_cache()); if (error_description) { *error_description = error_page::LocalizedError::GetErrorDetails( - error.domain(), error.reason(), is_post); + error.domain(), error.reason(), http_method == "POST"); } }
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h index 8f7c778..a32c277 100644 --- a/chrome/renderer/chrome_content_renderer_client.h +++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -55,10 +55,6 @@ struct WebPluginInfo; } -namespace error_page { -class Error; -} - namespace network_hints { class PrescientNetworkingDispatcher; } @@ -110,18 +106,19 @@ const GURL& url) override; bool ShouldTrackUseCounter(const GURL& url) override; void PrepareErrorPage(content::RenderFrame* render_frame, - const blink::WebURLRequest& failed_request, const blink::WebURLError& error, + const std::string& http_method, + bool ignoring_cache, std::string* error_html) override; - void PrepareErrorPageForHttpStatusError( - content::RenderFrame* render_frame, - const blink::WebURLRequest& failed_request, - const GURL& unreachable_url, - int http_status, - std::string* error_html) override; + void PrepareErrorPageForHttpStatusError(content::RenderFrame* render_frame, + const GURL& unreachable_url, + const std::string& http_method, + bool ignoring_cache, + int http_status, + std::string* error_html) override; - void GetErrorDescription(const blink::WebURLRequest& failed_request, - const blink::WebURLError& error, + void GetErrorDescription(const blink::WebURLError& error, + const std::string& http_method, base::string16* error_description) override; bool DeferMediaLoad(content::RenderFrame* render_frame, @@ -258,15 +255,6 @@ void GetInterface(const std::string& name, mojo::ScopedMessagePipeHandle request_handle) override; - void PrepareErrorPageInternal(content::RenderFrame* render_frame, - const blink::WebURLRequest& failed_request, - const error_page::Error& error, - std::string* error_html); - - void GetErrorDescriptionInternal(const blink::WebURLRequest& failed_request, - const error_page::Error& error, - base::string16* error_description); - // Time at which this object was created. This is very close to the time at // which the RendererMain function was entered. base::TimeTicks main_entry_time_;
diff --git a/chrome/renderer/net/net_error_helper.cc b/chrome/renderer/net/net_error_helper.cc index 9ec1b50..d90331d 100644 --- a/chrome/renderer/net/net_error_helper.cc +++ b/chrome/renderer/net/net_error_helper.cc
@@ -86,7 +86,7 @@ NetErrorHelperCore::PageType GetLoadingPageType( blink::WebDocumentLoader* document_loader) { - GURL url = document_loader->GetRequest().Url(); + GURL url = document_loader->GetUrl(); if (!url.is_valid() || url.spec() != kUnreachableWebDataURL) return NetErrorHelperCore::NON_ERROR_PAGE; return NetErrorHelperCore::ERROR_PAGE;
diff --git a/chrome/services/app_service/public/cpp/app_registry_cache.cc b/chrome/services/app_service/public/cpp/app_registry_cache.cc index b1546ea..0f1a516 100644 --- a/chrome/services/app_service/public/cpp/app_registry_cache.cc +++ b/chrome/services/app_service/public/cpp/app_registry_cache.cc
@@ -47,37 +47,54 @@ } void AppRegistryCache::OnApps(std::vector<apps::mojom::AppPtr> deltas) { - for (const auto& delta : deltas) { - auto iter = states_.find(delta->app_id); - if (iter == states_.end()) { - // The previous state is missing. Create an AppPtr to be that previous - // state, and copy over the mandatory fields. All other fields are the - // zero "unknown" value. - apps::mojom::AppPtr state = apps::mojom::App::New(); - state->app_type = delta->app_type; - state->app_id = delta->app_id; + DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_); - using Pair = std::pair<std::string, apps::mojom::AppPtr>; - iter = states_.insert(Pair(delta->app_id, std::move(state))).first; - } + // TODO(nigeltao): do we need to do anything special for OnApps calling + // observers calling ForEachApp calling callbacks calling OnApps? + deltas_in_progress_.clear(); - // Merge the delta, updating the internal states_ map. We do this before we - // notify the observers, so that if an observer calls back into the cache, - // it will see a consistent snapshot. - // - // We also keep (as the clone variable) the states_ value before the merge, - // so that the observers can know which fields (such as name, icon key or - // readiness) have changed. - apps::mojom::AppPtr clone = iter->second.Clone(); - AppUpdate::Merge(iter->second.get(), delta); - - for (auto& obs : observers_) { - obs.OnAppUpdate(AppUpdate(clone, delta)); + // Merge any deltas elements that have the same app_id. If an observer's + // OnAppUpdate calls back into this AppRegistryCache then we can therefore + // present a single delta for any given app_id. + for (auto& delta : deltas) { + auto iter = deltas_in_progress_.find(delta->app_id); + if (iter != deltas_in_progress_.end()) { + AppUpdate::Merge(iter->second, delta.get()); + } else { + deltas_in_progress_[delta->app_id] = delta.get(); } } + + // The remaining for loops range over the deltas_in_progress_ map, not the + // deltas vector, so that OnAppUpdate is called only once per unique app_id. + + // Notify the observers for every de-duplicated delta. + for (const auto& delta : deltas_in_progress_) { + auto iter = states_.find(delta.second->app_id); + apps::mojom::App* state = + (iter != states_.end()) ? iter->second.get() : nullptr; + + for (auto& obs : observers_) { + obs.OnAppUpdate(AppUpdate(state, delta.second)); + } + } + + // Update the states for every de-duplicated delta. + for (const auto& delta : deltas_in_progress_) { + auto iter = states_.find(delta.second->app_id); + if (iter != states_.end()) { + AppUpdate::Merge(iter->second.get(), delta.second); + } else { + states_.insert( + std::make_pair(delta.second->app_id, delta.second->Clone())); + } + } + deltas_in_progress_.clear(); } apps::mojom::AppType AppRegistryCache::GetAppType(const std::string& app_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_); + auto iter = states_.find(app_id); if (iter != states_.end()) { return iter->second->app_type;
diff --git a/chrome/services/app_service/public/cpp/app_registry_cache.h b/chrome/services/app_service/public/cpp/app_registry_cache.h index 7e1bab8..d95ca047 100644 --- a/chrome/services/app_service/public/cpp/app_registry_cache.h +++ b/chrome/services/app_service/public/cpp/app_registry_cache.h
@@ -10,6 +10,7 @@ #include "base/macros.h" #include "base/observer_list_types.h" +#include "base/sequence_checker.h" #include "chrome/services/app_service/public/cpp/app_update.h" namespace apps { @@ -67,25 +68,47 @@ // Notifies all observers of state-and-delta AppUpdate's (the state comes // from the internal cache, the delta comes from the argument) and then // merges the cached states with the deltas. + // + // The callee may modify the deltas. void OnApps(std::vector<apps::mojom::AppPtr> deltas); apps::mojom::AppType GetAppType(const std::string& app_id); // Calls f, a void-returning function whose arguments are (const - // apps::AppUpdate&), on each app in the cache. The AppUpdate (a - // state-and-delta) is equivalent to the delta being "all unknown" or "no - // changes" and the state being the "sum" of all previous deltas. None of the - // AppUpdate's FooChanged methods should return true. + // apps::AppUpdate&), on each app in the cache. // // f's argument is an apps::AppUpdate instead of an apps::mojom::AppPtr so // that callers can more easily share code with Observer::OnAppUpdate (which - // also takes an apps::AppUpdate). + // also takes an apps::AppUpdate), and an apps::AppUpdate also has a + // StateIsNull method. // // The apps::AppUpdate argument to f shouldn't be accessed after f returns. + // + // f must be synchronous, and if it asynchronously calls ForEachApp again, + // it's not guaranteed to see a consistent state. template <typename FunctionType> void ForEachApp(FunctionType f) { - for (const auto& iter : states_) { - f(apps::AppUpdate(iter.second, iter.second)); + DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_); + + for (const auto& s_iter : states_) { + const apps::mojom::App* state = s_iter.second.get(); + + auto d_iter = deltas_in_progress_.find(s_iter.first); + const apps::mojom::App* delta = + (d_iter != deltas_in_progress_.end()) ? d_iter->second : nullptr; + + f(apps::AppUpdate(state, delta)); + } + + for (const auto& d_iter : deltas_in_progress_) { + const apps::mojom::App* delta = d_iter.second; + + auto s_iter = states_.find(d_iter.first); + if (s_iter != states_.end()) { + continue; + } + + f(apps::AppUpdate(nullptr, delta)); } } @@ -94,11 +117,23 @@ // return true (and call f) if there is such an app, otherwise it will return // false (and not call f). The AppUpdate argument to f has the same semantics // as for ForEachApp, above. + // + // f must be synchronous, and if it asynchronously calls ForEachApp again, + // it's not guaranteed to see a consistent state. template <typename FunctionType> bool ForOneApp(const std::string& app_id, FunctionType f) { - auto iter = states_.find(app_id); - if (iter != states_.end()) { - f(apps::AppUpdate(iter->second, iter->second)); + DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_); + + auto s_iter = states_.find(app_id); + const apps::mojom::App* state = + (s_iter != states_.end()) ? s_iter->second.get() : nullptr; + + auto d_iter = deltas_in_progress_.find(app_id); + const apps::mojom::App* delta = + (d_iter != deltas_in_progress_.end()) ? d_iter->second : nullptr; + + if (state || delta) { + f(apps::AppUpdate(state, delta)); return true; } return false; @@ -110,6 +145,11 @@ // Maps from app_id to the latest state: the "sum" of all previous deltas. std::map<std::string, apps::mojom::AppPtr> states_; + // Maps from app_id to the deltas being processed by OnApps. + std::map<std::string, apps::mojom::App*> deltas_in_progress_; + + SEQUENCE_CHECKER(my_sequence_checker_); + DISALLOW_COPY_AND_ASSIGN(AppRegistryCache); };
diff --git a/chrome/services/app_service/public/cpp/app_registry_cache_unittest.cc b/chrome/services/app_service/public/cpp/app_registry_cache_unittest.cc index 9cd3780..f7180e4 100644 --- a/chrome/services/app_service/public/cpp/app_registry_cache_unittest.cc +++ b/chrome/services/app_service/public/cpp/app_registry_cache_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 <map> + #include "chrome/services/app_service/public/cpp/app_registry_cache.h" #include "testing/gtest/include/gtest/gtest.h" @@ -52,18 +54,69 @@ ~RecursiveObserver() override { cache_->RemoveObserver(this); } + void PrepareForOnApps(int expected_num_apps, + const std::string& expected_name_for_p) { + expected_name_for_p_ = expected_name_for_p; + expected_num_apps_ = expected_num_apps; + num_apps_seen_on_app_update_ = 0; + names_.clear(); + } + + int NumAppsSeenOnAppUpdate() { return num_apps_seen_on_app_update_; } + protected: // apps::AppRegistryCache::Observer overrides. void OnAppUpdate(const apps::AppUpdate& outer) override { - cache_->ForOneApp(outer.AppId(), [&outer](const apps::AppUpdate& inner) { - EXPECT_EQ(outer.AppType(), inner.AppType()); - EXPECT_EQ(outer.AppId(), inner.AppId()); - EXPECT_EQ(outer.Readiness(), inner.Readiness()); - EXPECT_EQ(outer.Name(), inner.Name()); + int num_apps = 0; + cache_->ForEachApp([this, &outer, &num_apps](const apps::AppUpdate& inner) { + if (num_apps_seen_on_app_update_ == 0) { + // If this is the first time that OnAppUpdate is called, after a + // PrepareForOnApps call, then just populate the names_ map. + names_[inner.AppId()] = inner.Name(); + } else { + // Otherwise, check that the names found during this OnAppUpdate call + // match those during the first OnAppUpdate call. + auto iter = names_.find(inner.AppId()); + EXPECT_EQ(inner.Name(), (iter != names_.end()) ? iter->second : ""); + } + + if (outer.AppId() == inner.AppId()) { + ExpectEq(outer, inner); + } + + if (inner.AppId() == "p") { + EXPECT_EQ(expected_name_for_p_, inner.Name()); + } + + num_apps++; }); + EXPECT_EQ(expected_num_apps_, num_apps); + + EXPECT_FALSE(cache_->ForOneApp( + "no_such_app_id", + [&outer](const apps::AppUpdate& inner) { ExpectEq(outer, inner); })); + + EXPECT_TRUE(cache_->ForOneApp( + outer.AppId(), + [&outer](const apps::AppUpdate& inner) { ExpectEq(outer, inner); })); + + num_apps_seen_on_app_update_++; + } + + static void ExpectEq(const apps::AppUpdate& outer, + const apps::AppUpdate& inner) { + EXPECT_EQ(outer.AppType(), inner.AppType()); + EXPECT_EQ(outer.AppId(), inner.AppId()); + EXPECT_EQ(outer.StateIsNull(), inner.StateIsNull()); + EXPECT_EQ(outer.Readiness(), inner.Readiness()); + EXPECT_EQ(outer.Name(), inner.Name()); } apps::AppRegistryCache* cache_; + std::string expected_name_for_p_; + int expected_num_apps_; + std::map<std::string, std::string> names_; + int num_apps_seen_on_app_update_; }; TEST_F(AppRegistryCacheTest, ForEachApp) { @@ -169,19 +222,25 @@ apps::AppRegistryCache cache; RecursiveObserver observer(&cache); + observer.PrepareForOnApps(2, "peach"); deltas.clear(); deltas.push_back(MakeApp("o", "orange")); deltas.push_back(MakeApp("p", "peach")); cache.OnApps(std::move(deltas)); + EXPECT_EQ(2, observer.NumAppsSeenOnAppUpdate()); + observer.PrepareForOnApps(3, "pear"); deltas.clear(); deltas.push_back(MakeApp("p", "pear", apps::mojom::Readiness::kReady)); deltas.push_back(MakeApp("q", "quince")); cache.OnApps(std::move(deltas)); + EXPECT_EQ(2, observer.NumAppsSeenOnAppUpdate()); + observer.PrepareForOnApps(3, "plum"); deltas.clear(); deltas.push_back(MakeApp("p", "pear")); deltas.push_back(MakeApp("p", "pear")); deltas.push_back(MakeApp("p", "plum")); cache.OnApps(std::move(deltas)); + EXPECT_EQ(1, observer.NumAppsSeenOnAppUpdate()); }
diff --git a/chrome/services/app_service/public/cpp/app_update.cc b/chrome/services/app_service/public/cpp/app_update.cc index c15b24c..ea08523 100644 --- a/chrome/services/app_service/public/cpp/app_update.cc +++ b/chrome/services/app_service/public/cpp/app_update.cc
@@ -9,9 +9,11 @@ namespace apps { // static -void AppUpdate::Merge(apps::mojom::App* state, - const apps::mojom::AppPtr& delta) { +void AppUpdate::Merge(apps::mojom::App* state, const apps::mojom::App* delta) { DCHECK(state); + if (!delta) { + return; + } DCHECK(delta->app_type == state->app_type); DCHECK(delta->app_id == state->app_id); @@ -35,80 +37,105 @@ // updated. } -AppUpdate::AppUpdate(const apps::mojom::AppPtr& state, - const apps::mojom::AppPtr& delta) - : state_(state), delta_(delta) {} +AppUpdate::AppUpdate(const apps::mojom::App* state, + const apps::mojom::App* delta) + : state_(state), delta_(delta) { + DCHECK(state_ || delta_); + if (state_ && delta_) { + DCHECK(state_->app_type == delta->app_type); + DCHECK(state_->app_id == delta->app_id); + } +} + +bool AppUpdate::StateIsNull() const { + return state_ == nullptr; +} apps::mojom::AppType AppUpdate::AppType() const { - DCHECK(delta_->app_type == state_->app_type); - return delta_->app_type; + return delta_ ? delta_->app_type : state_->app_type; } const std::string& AppUpdate::AppId() const { - DCHECK(delta_->app_id == state_->app_id); - return delta_->app_id; + return delta_ ? delta_->app_id : state_->app_id; } apps::mojom::Readiness AppUpdate::Readiness() const { - return (delta_->readiness != apps::mojom::Readiness::kUnknown) - ? delta_->readiness - : state_->readiness; + if (delta_ && (delta_->readiness != apps::mojom::Readiness::kUnknown)) { + return delta_->readiness; + } + if (state_) { + return state_->readiness; + } + return apps::mojom::Readiness::kUnknown; } bool AppUpdate::ReadinessChanged() const { - return (delta_->readiness != apps::mojom::Readiness::kUnknown) && - (delta_->readiness != state_->readiness); + return delta_ && (delta_->readiness != apps::mojom::Readiness::kUnknown) && + (!state_ || (delta_->readiness != state_->readiness)); } const std::string& AppUpdate::Name() const { - if (delta_->name.has_value()) { + if (delta_ && delta_->name.has_value()) { return delta_->name.value(); } - if (state_->name.has_value()) { + if (state_ && state_->name.has_value()) { return state_->name.value(); } return base::EmptyString(); } bool AppUpdate::NameChanged() const { - return delta_->name.has_value() && (delta_->name != state_->name); + return delta_ && delta_->name.has_value() && + (!state_ || (delta_->name != state_->name)); } apps::mojom::IconKeyPtr AppUpdate::IconKey() const { - if (!delta_->icon_key.is_null()) { + if (delta_ && !delta_->icon_key.is_null()) { return delta_->icon_key.Clone(); } - if (!state_->icon_key.is_null()) { + if (state_ && !state_->icon_key.is_null()) { return state_->icon_key.Clone(); } return apps::mojom::IconKeyPtr(); } bool AppUpdate::IconKeyChanged() const { - return !delta_->icon_key.is_null() && - !delta_->icon_key.Equals(state_->icon_key); + return delta_ && !delta_->icon_key.is_null() && + (!state_ || !delta_->icon_key.Equals(state_->icon_key)); } apps::mojom::OptionalBool AppUpdate::ShowInLauncher() const { - return (delta_->show_in_launcher != apps::mojom::OptionalBool::kUnknown) - ? delta_->show_in_launcher - : state_->show_in_launcher; + if (delta_ && + (delta_->show_in_launcher != apps::mojom::OptionalBool::kUnknown)) { + return delta_->show_in_launcher; + } + if (state_) { + return state_->show_in_launcher; + } + return apps::mojom::OptionalBool::kUnknown; } bool AppUpdate::ShowInLauncherChanged() const { - return (delta_->show_in_launcher != apps::mojom::OptionalBool::kUnknown) && - (delta_->show_in_launcher != state_->show_in_launcher); + return delta_ && + (delta_->show_in_launcher != apps::mojom::OptionalBool::kUnknown) && + (!state_ || (delta_->show_in_launcher != state_->show_in_launcher)); } apps::mojom::OptionalBool AppUpdate::ShowInSearch() const { - return (delta_->show_in_search != apps::mojom::OptionalBool::kUnknown) - ? delta_->show_in_search - : state_->show_in_search; + if (delta_ && + (delta_->show_in_search != apps::mojom::OptionalBool::kUnknown)) { + return delta_->show_in_search; + } + if (state_) { + return state_->show_in_search; + } + return apps::mojom::OptionalBool::kUnknown; } bool AppUpdate::ShowInSearchChanged() const { - return (delta_->show_in_search != apps::mojom::OptionalBool::kUnknown) && - (delta_->show_in_search != state_->show_in_search); + return delta_ && + (delta_->show_in_search != apps::mojom::OptionalBool::kUnknown) && + (!state_ || (delta_->show_in_search != state_->show_in_search)); } } // namespace apps
diff --git a/chrome/services/app_service/public/cpp/app_update.h b/chrome/services/app_service/public/cpp/app_update.h index 2a7aa0f..5a7b1f9 100644 --- a/chrome/services/app_service/public/cpp/app_update.h +++ b/chrome/services/app_service/public/cpp/app_update.h
@@ -15,6 +15,10 @@ // with "addition" or "merging" simply being that the most recent version of // each field "wins". // +// The state may be nullptr, meaning that there are no previous deltas. +// Alternatively, the delta may be nullptr, meaning that there is no change in +// state. At least one of state and delta must be non-nullptr. +// // Almost all of an AppPtr's fields are optional. For example, if an app's name // hasn't changed, then a delta doesn't necessarily have to contain a copy of // the name, as the prior state should already contain it. @@ -36,11 +40,16 @@ // See //chrome/services/app_service/README.md for more details. class AppUpdate { public: - // Modifies state by copying over all of delta's known fields: those fields - // whose values aren't "unknown". - static void Merge(apps::mojom::App* state, const apps::mojom::AppPtr& delta); + // Modifies |state| by copying over all of |delta|'s known fields: those + // fields whose values aren't "unknown". The |state| may not be nullptr. + static void Merge(apps::mojom::App* state, const apps::mojom::App* delta); - AppUpdate(const apps::mojom::AppPtr& state, const apps::mojom::AppPtr& delta); + // At most one of |state| or |delta| may be nullptr. + AppUpdate(const apps::mojom::App* state, const apps::mojom::App* delta); + + // Returns whether this is the first update for the given AppId. + // Equivalently, there are no previous deltas for the AppId. + bool StateIsNull() const; apps::mojom::AppType AppType() const; @@ -62,8 +71,8 @@ bool ShowInSearchChanged() const; private: - const apps::mojom::AppPtr& state_; - const apps::mojom::AppPtr& delta_; + const apps::mojom::App* state_; + const apps::mojom::App* delta_; DISALLOW_COPY_AND_ASSIGN(AppUpdate); };
diff --git a/chrome/services/app_service/public/cpp/app_update_unittest.cc b/chrome/services/app_service/public/cpp/app_update_unittest.cc index 26dfdde..899eb2d6 100644 --- a/chrome/services/app_service/public/cpp/app_update_unittest.cc +++ b/chrome/services/app_service/public/cpp/app_update_unittest.cc
@@ -5,12 +5,179 @@ #include "chrome/services/app_service/public/cpp/app_update.h" #include "testing/gtest/include/gtest/gtest.h" -class AppUpdateTest : public testing::Test {}; +namespace { +const apps::mojom::AppType app_type = apps::mojom::AppType::kArc; +const char app_id[] = "abcdefgh"; +const char test_name_0[] = "Inigo Montoya"; +const char test_name_1[] = "Dread Pirate Roberts"; +} // namespace -TEST_F(AppUpdateTest, BasicOps) { - const apps::mojom::AppType app_type = apps::mojom::AppType::kArc; - const std::string app_id = "abcdefgh"; +class AppUpdateTest : public testing::Test { + protected: + apps::mojom::Readiness expect_readiness_; + bool expect_readiness_changed_; + std::string expect_name_; + bool expect_name_changed_; + + apps::mojom::IconKeyPtr expect_icon_key_; + bool expect_icon_key_changed_; + + apps::mojom::OptionalBool expect_show_in_launcher_; + bool expect_show_in_launcher_changed_; + + apps::mojom::OptionalBool expect_show_in_search_; + bool expect_show_in_search_changed_; + + void ExpectNoChange() { + expect_readiness_changed_ = false; + expect_name_changed_ = false; + expect_icon_key_changed_ = false; + expect_show_in_launcher_changed_ = false; + expect_show_in_search_changed_ = false; + } + + void CheckExpects(const apps::AppUpdate& u) { + EXPECT_EQ(expect_readiness_, u.Readiness()); + EXPECT_EQ(expect_readiness_changed_, u.ReadinessChanged()); + + EXPECT_EQ(expect_name_, u.Name()); + EXPECT_EQ(expect_name_changed_, u.NameChanged()); + + EXPECT_EQ(expect_icon_key_, u.IconKey()); + EXPECT_EQ(expect_icon_key_changed_, u.IconKeyChanged()); + + EXPECT_EQ(expect_show_in_launcher_, u.ShowInLauncher()); + EXPECT_EQ(expect_show_in_launcher_changed_, u.ShowInLauncherChanged()); + + EXPECT_EQ(expect_show_in_search_, u.ShowInSearch()); + EXPECT_EQ(expect_show_in_search_changed_, u.ShowInSearchChanged()); + } + + void TestAppUpdate(apps::mojom::App* state, apps::mojom::App* delta) { + apps::AppUpdate u(state, delta); + + EXPECT_EQ(app_type, u.AppType()); + EXPECT_EQ(app_id, u.AppId()); + EXPECT_EQ(state == nullptr, u.StateIsNull()); + + expect_readiness_ = apps::mojom::Readiness::kUnknown; + expect_name_ = ""; + expect_icon_key_ = nullptr; + expect_show_in_launcher_ = apps::mojom::OptionalBool::kUnknown; + expect_show_in_search_ = apps::mojom::OptionalBool::kUnknown; + ExpectNoChange(); + CheckExpects(u); + + if (delta) { + delta->name = test_name_0; + expect_name_ = test_name_0; + expect_name_changed_ = true; + CheckExpects(u); + } + + if (state) { + state->name = test_name_0; + expect_name_ = test_name_0; + expect_name_changed_ = false; + CheckExpects(u); + } + + if (delta) { + delta->readiness = apps::mojom::Readiness::kReady; + expect_readiness_ = apps::mojom::Readiness::kReady; + expect_readiness_changed_ = true; + CheckExpects(u); + + delta->name = base::nullopt; + expect_name_ = state ? test_name_0 : ""; + expect_name_changed_ = false; + CheckExpects(u); + } + + if (state) { + apps::AppUpdate::Merge(state, delta); + ExpectNoChange(); + CheckExpects(u); + } + + if (delta) { + delta->readiness = apps::mojom::Readiness::kDisabledByPolicy; + expect_readiness_ = apps::mojom::Readiness::kDisabledByPolicy; + expect_readiness_changed_ = true; + delta->name = test_name_1; + expect_name_ = test_name_1; + expect_name_changed_ = true; + CheckExpects(u); + } + + // IconKey tests. + + if (state) { + auto x = apps::mojom::IconKey::New(apps::mojom::IconType::kResource, 100, + std::string()); + state->icon_key = x.Clone(); + expect_icon_key_ = x.Clone(); + expect_icon_key_changed_ = false; + CheckExpects(u); + } + + if (delta) { + auto x = apps::mojom::IconKey::New(apps::mojom::IconType::kExtension, 0, + "one hundred"); + delta->icon_key = x.Clone(); + expect_icon_key_ = x.Clone(); + expect_icon_key_changed_ = true; + CheckExpects(u); + } + + if (state) { + apps::AppUpdate::Merge(state, delta); + ExpectNoChange(); + CheckExpects(u); + } + + // ShowInSearch tests. + + if (state) { + state->show_in_search = apps::mojom::OptionalBool::kFalse; + expect_show_in_search_ = apps::mojom::OptionalBool::kFalse; + expect_show_in_search_changed_ = false; + CheckExpects(u); + } + + if (delta) { + delta->show_in_search = apps::mojom::OptionalBool::kTrue; + expect_show_in_search_ = apps::mojom::OptionalBool::kTrue; + expect_show_in_search_changed_ = true; + CheckExpects(u); + } + + if (state) { + apps::AppUpdate::Merge(state, delta); + ExpectNoChange(); + CheckExpects(u); + } + } +}; + +TEST_F(AppUpdateTest, StateIsNonNull) { + apps::mojom::AppPtr state = apps::mojom::App::New(); + state->app_type = app_type; + state->app_id = app_id; + + TestAppUpdate(state.get(), nullptr); +} + +TEST_F(AppUpdateTest, DeltaIsNonNull) { + apps::mojom::AppPtr delta = apps::mojom::App::New(); + delta->app_type = app_type; + delta->app_id = app_id; + + TestAppUpdate(nullptr, delta.get()); +} + +TEST_F(AppUpdateTest, BothAreNonNull) { apps::mojom::AppPtr state = apps::mojom::App::New(); state->app_type = app_type; state->app_id = app_id; @@ -19,140 +186,5 @@ delta->app_type = app_type; delta->app_id = app_id; - apps::AppUpdate u(state, delta); - - EXPECT_EQ(app_type, u.AppType()); - EXPECT_EQ(app_id, u.AppId()); - - EXPECT_FALSE(u.ReadinessChanged()); - EXPECT_FALSE(u.NameChanged()); - EXPECT_FALSE(u.ShowInLauncherChanged()); - - EXPECT_EQ(apps::mojom::Readiness::kUnknown, u.Readiness()); - EXPECT_EQ("", u.Name()); - EXPECT_EQ(apps::mojom::OptionalBool::kUnknown, u.ShowInLauncher()); - - delta->name = "Inigo Montoya"; - - EXPECT_FALSE(u.ReadinessChanged()); - EXPECT_TRUE(u.NameChanged()); - EXPECT_FALSE(u.ShowInLauncherChanged()); - - EXPECT_EQ(apps::mojom::Readiness::kUnknown, u.Readiness()); - EXPECT_NE(apps::mojom::Readiness::kReady, state->readiness); - EXPECT_EQ("Inigo Montoya", u.Name()); - EXPECT_NE("Inigo Montoya", state->name); - EXPECT_EQ(apps::mojom::OptionalBool::kUnknown, u.ShowInLauncher()); - EXPECT_EQ(apps::mojom::OptionalBool::kUnknown, state->show_in_launcher); - - state->name = "Inigo Montoya"; - - EXPECT_FALSE(u.ReadinessChanged()); - EXPECT_FALSE(u.NameChanged()); - EXPECT_FALSE(u.ShowInLauncherChanged()); - - EXPECT_EQ(apps::mojom::Readiness::kUnknown, u.Readiness()); - EXPECT_NE(apps::mojom::Readiness::kReady, state->readiness); - EXPECT_EQ("Inigo Montoya", u.Name()); - EXPECT_EQ("Inigo Montoya", state->name); - EXPECT_EQ(apps::mojom::OptionalBool::kUnknown, u.ShowInLauncher()); - EXPECT_EQ(apps::mojom::OptionalBool::kUnknown, state->show_in_launcher); - - delta->readiness = apps::mojom::Readiness::kReady; - - EXPECT_TRUE(u.ReadinessChanged()); - EXPECT_FALSE(u.NameChanged()); - EXPECT_FALSE(u.ShowInLauncherChanged()); - - EXPECT_EQ(apps::mojom::Readiness::kReady, u.Readiness()); - EXPECT_NE(apps::mojom::Readiness::kReady, state->readiness); - EXPECT_EQ("Inigo Montoya", u.Name()); - EXPECT_EQ("Inigo Montoya", state->name); - EXPECT_EQ(apps::mojom::OptionalBool::kUnknown, u.ShowInLauncher()); - EXPECT_EQ(apps::mojom::OptionalBool::kUnknown, state->show_in_launcher); - - delta->name = base::nullopt; - - EXPECT_TRUE(u.ReadinessChanged()); - EXPECT_FALSE(u.NameChanged()); - EXPECT_FALSE(u.ShowInLauncherChanged()); - - EXPECT_EQ(apps::mojom::Readiness::kReady, u.Readiness()); - EXPECT_NE(apps::mojom::Readiness::kReady, state->readiness); - EXPECT_EQ("Inigo Montoya", u.Name()); - EXPECT_EQ("Inigo Montoya", state->name); - EXPECT_EQ(apps::mojom::OptionalBool::kUnknown, u.ShowInLauncher()); - EXPECT_EQ(apps::mojom::OptionalBool::kUnknown, state->show_in_launcher); - - apps::AppUpdate::Merge(state.get(), delta); - - EXPECT_FALSE(u.ReadinessChanged()); - EXPECT_FALSE(u.NameChanged()); - EXPECT_FALSE(u.ShowInLauncherChanged()); - - EXPECT_EQ(apps::mojom::Readiness::kReady, u.Readiness()); - EXPECT_EQ(apps::mojom::Readiness::kReady, state->readiness); - EXPECT_EQ("Inigo Montoya", u.Name()); - EXPECT_EQ("Inigo Montoya", state->name); - EXPECT_EQ(apps::mojom::OptionalBool::kUnknown, u.ShowInLauncher()); - EXPECT_EQ(apps::mojom::OptionalBool::kUnknown, state->show_in_launcher); - - delta->readiness = apps::mojom::Readiness::kDisabledByPolicy; - delta->name = "Dread Pirate Roberts"; - - EXPECT_TRUE(u.ReadinessChanged()); - EXPECT_TRUE(u.NameChanged()); - EXPECT_FALSE(u.ShowInLauncherChanged()); - - EXPECT_NE(apps::mojom::Readiness::kReady, u.Readiness()); - EXPECT_EQ(apps::mojom::Readiness::kReady, state->readiness); - EXPECT_NE("Inigo Montoya", u.Name()); - EXPECT_EQ("Inigo Montoya", state->name); - EXPECT_EQ(apps::mojom::OptionalBool::kUnknown, u.ShowInLauncher()); - EXPECT_EQ(apps::mojom::OptionalBool::kUnknown, state->show_in_launcher); - - // IconKey tests. - - EXPECT_TRUE(u.IconKey().is_null()); - EXPECT_FALSE(u.IconKeyChanged()); - - state->icon_key = apps::mojom::IconKey::New(apps::mojom::IconType::kResource, - 100, std::string()); - - EXPECT_FALSE(u.IconKey().is_null()); - EXPECT_EQ(apps::mojom::IconType::kResource, u.IconKey()->icon_type); - EXPECT_FALSE(u.IconKeyChanged()); - - delta->icon_key = apps::mojom::IconKey::New(apps::mojom::IconType::kExtension, - 0, "one hundred"); - - EXPECT_FALSE(u.IconKey().is_null()); - EXPECT_EQ(apps::mojom::IconType::kExtension, u.IconKey()->icon_type); - EXPECT_TRUE(u.IconKeyChanged()); - - apps::AppUpdate::Merge(state.get(), delta); - - EXPECT_FALSE(u.IconKey().is_null()); - EXPECT_EQ(apps::mojom::IconType::kExtension, u.IconKey()->icon_type); - EXPECT_FALSE(u.IconKeyChanged()); - - // ShowInSearch tests. - - EXPECT_EQ(apps::mojom::OptionalBool::kUnknown, u.ShowInSearch()); - EXPECT_FALSE(u.ShowInSearchChanged()); - - state->show_in_search = apps::mojom::OptionalBool::kFalse; - - EXPECT_EQ(apps::mojom::OptionalBool::kFalse, u.ShowInSearch()); - EXPECT_FALSE(u.ShowInSearchChanged()); - - delta->show_in_search = apps::mojom::OptionalBool::kTrue; - - EXPECT_EQ(apps::mojom::OptionalBool::kTrue, u.ShowInSearch()); - EXPECT_TRUE(u.ShowInSearchChanged()); - - apps::AppUpdate::Merge(state.get(), delta); - - EXPECT_EQ(apps::mojom::OptionalBool::kTrue, u.ShowInSearch()); - EXPECT_FALSE(u.ShowInSearchChanged()); + TestAppUpdate(state.get(), delta.get()); }
diff --git a/chrome/services/cups_ipp_parser/BUILD.gn b/chrome/services/cups_ipp_parser/BUILD.gn index 8022543..0628ec0 100644 --- a/chrome/services/cups_ipp_parser/BUILD.gn +++ b/chrome/services/cups_ipp_parser/BUILD.gn
@@ -18,6 +18,7 @@ deps = [ "//base", "//mojo/public/cpp/bindings", + "//net", ] public_deps = [
diff --git a/chrome/services/cups_ipp_parser/ipp_parser.cc b/chrome/services/cups_ipp_parser/ipp_parser.cc index b8a7161..0b50e78 100644 --- a/chrome/services/cups_ipp_parser/ipp_parser.cc +++ b/chrome/services/cups_ipp_parser/ipp_parser.cc
@@ -18,6 +18,7 @@ using ipp_converter::HttpHeader; using ipp_converter::kCarriage; +using ipp_converter::kIppSentinel; // Log debugging error and send empty response, signalling error. void Fail(const std::string& error_log, IppParser::ParseIppCallback cb) { @@ -74,13 +75,13 @@ return -1; } - auto idx = request.find(ipp_converter::kIppSentinel, end_of_headers); + auto idx = request.find(kIppSentinel, end_of_headers); if (idx == base::StringPiece::npos) { return -1; } // Advance to start and check existence or end of request. - idx += strlen(ipp_converter::kIppSentinel); + idx += strlen(kIppSentinel); return idx <= request.size() ? idx : -1; }
diff --git a/chrome/services/cups_ipp_parser/public/cpp/BUILD.gn b/chrome/services/cups_ipp_parser/public/cpp/BUILD.gn index c84067b..968feed3 100644 --- a/chrome/services/cups_ipp_parser/public/cpp/BUILD.gn +++ b/chrome/services/cups_ipp_parser/public/cpp/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//printing/buildflags/buildflags.gni") +import("//testing/libfuzzer/fuzzer_test.gni") if (use_cups) { source_set("cpp") { @@ -14,7 +15,21 @@ deps = [ "//base", "//chrome/services/cups_ipp_parser/public/mojom", + "//net", "//printing", ] + + configs += [ "//printing:cups" ] + } + + fuzzer_test("ipp_message_parser_fuzzer") { + sources = [ + "ipp_message_parser_fuzzer.cc", + ] + deps = [ + ":cpp", + ] + + dict = "ipp_message_parser_fuzzer.dict" } }
diff --git a/chrome/services/cups_ipp_parser/public/cpp/ipp_message_parser_fuzzer.cc b/chrome/services/cups_ipp_parser/public/cpp/ipp_message_parser_fuzzer.cc new file mode 100644 index 0000000..73ad053 --- /dev/null +++ b/chrome/services/cups_ipp_parser/public/cpp/ipp_message_parser_fuzzer.cc
@@ -0,0 +1,25 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <stddef.h> +#include <stdint.h> + +#include <string> + +#include "chrome/services/cups_ipp_parser/public/cpp/ipp_converter.h" + +// This turns off service error logging. +struct Environment { + Environment() { logging::SetMinLogLevel(logging::LOG_FATAL); } +}; + +// Entry point for LibFuzzer. +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + static Environment env; + + auto ipp = ipp_converter::ParseIppMessage({data, size}); + ipp_converter::ConvertIppToMojo(ipp.release()); + + return 0; +}
diff --git a/chrome/services/cups_ipp_parser/public/cpp/ipp_message_parser_fuzzer.dict b/chrome/services/cups_ipp_parser/public/cpp/ipp_message_parser_fuzzer.dict new file mode 100644 index 0000000..daf499fe --- /dev/null +++ b/chrome/services/cups_ipp_parser/public/cpp/ipp_message_parser_fuzzer.dict
@@ -0,0 +1,98 @@ + +# IPP end-of-attributes tag +"\x03" + +# TODO(luum): Add relevant opcodes + +# All IPP attributes +"charset-configured" +"charset-supported" +"color-supported" +"compression-supported" +"copies-default" +"copies-supported" +"document-format-default" +"document-format-supported" +"document-password-supported" +"feed-orientation-default" +"feed-orientation-supported" +"finishings-col-database" +"finishings-col-default" +"finishings-col-ready" +"finishings-col-supported" +"finishings-default" +"finishings-ready" +"finishings-supported" +"generated-natural-language-supported" +"identify-actions-default" +"identify-actions-supported" +"ipp-features-supported" +"ipp-versions-supported" +"job-account-id-default" +"job-account-id-supported" +"job-accounting-user-id-default" +"job-accounting-user-id-supported" +"job-constraints-supported" +"job-creation-attributes-supported" +"job-ids-supported" +"job-password-supported" +"job-password-encryption-supported" +"job-resolvers-supported" +"media-bottom-margin-supported" +"media-col-database" +"media-col-database.media-source-properties" +"media-col-default" +"media-col-ready" +"media-col-ready.media-source-properties" +"media-col-supported" +"media-default" +"media-left-margin-supported" +"media-ready" +"media-right-margin-supported" +"media-size-supported" +"media-source-supported" +"media-supported" +"media-top-margin-supported" +"media-type-supported" +"multiple-document-jobs-supported" +"multiple-operation-timeout" +"multiple-operation-timeout-action" +"natural-language-configured" +"operations-supported" +"orientation-requested-default" +"orientation-requested-supported" +"output-bin-default" +"output-bin-supported" +"overrides-supported" +"page-ranges-supported" +"preferred-attributes-supported" +"print-color-mode-default" +"print-color-mode-supported" +"print-content-optimize-default" +"print-content-optimize-supported" +"print-rendering-intent-default" +"print-rendering-intent-supported" +"print-quality-default" +"print-quality-supported" +"printer-current-time" +"printer-geo-location" +"printer-get-attributes-supported" +"printer-icc-profiles" +"printer-icons" +"printer-info" +"printer-location" +"printer-make-and-model" +"printer-mandatory-job-attributes" +"printer-name" +"printer-organization" +"printer-organizational-unit" +"printer-resolution-default" +"printer-resolution-supported" +"pwg-raster-document-resolution-supported" +"pwg-raster-document-sheet-back" +"pwg-raster-document-type-supported" +"sides-default" +"sides-supported" +"uri-security-supported" +"uri-authentication-supported" +"which-jobs-supported"
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 4d2e9c7..7ba5295 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2349,6 +2349,7 @@ "../browser/android/history_report/usage_reports_buffer_backend_unittest.cc", "../browser/android/locale/locale_template_url_loader_unittest.cc", "../browser/android/tab_web_contents_delegate_android_unittest.cc", + "../browser/ui/webui/version_handler_win_unittest.cc", # TODO(newt): move this to test_support_unit? "../browser/android/chrome_backup_agent_unittest.cc",
diff --git a/chrome/test/base/chrome_render_view_host_test_harness.cc b/chrome/test/base/chrome_render_view_host_test_harness.cc index 0e1fcd5..a2c4cc05a 100644 --- a/chrome/test/base/chrome_render_view_host_test_harness.cc +++ b/chrome/test/base/chrome_render_view_host_test_harness.cc
@@ -37,17 +37,15 @@ AccountTrackerServiceFactory::GetForProfile(profile); SigninErrorController* signin_error_controller = SigninErrorControllerFactory::GetForProfile(profile); - ProfileOAuth2TokenService* token_service = - ProfileOAuth2TokenServiceFactory::GetForProfile(profile); #if defined (OS_CHROMEOS) - std::unique_ptr<SigninManagerBase> signin( - new SigninManagerBase(signin_client, token_service, - account_tracker_service, signin_error_controller)); + std::unique_ptr<SigninManagerBase> signin(new SigninManagerBase( + signin_client, account_tracker_service, signin_error_controller)); signin->Initialize(NULL); return std::move(signin); #else std::unique_ptr<FakeSigninManager> manager(new FakeSigninManager( - signin_client, token_service, account_tracker_service, + signin_client, ProfileOAuth2TokenServiceFactory::GetForProfile(profile), + account_tracker_service, GaiaCookieManagerServiceFactory::GetForProfile(profile), signin_error_controller)); manager->Initialize(g_browser_process->local_state());
diff --git a/chrome/test/base/test_browser_window_aura.cc b/chrome/test/base/test_browser_window_aura.cc index 212ea8b..42a0683 100644 --- a/chrome/test/base/test_browser_window_aura.cc +++ b/chrome/test/base/test_browser_window_aura.cc
@@ -4,9 +4,10 @@ #include "chrome/test/base/test_browser_window_aura.h" -#include <utility> - #include "base/memory/ptr_util.h" +#include "chrome/browser/ui/browser.h" +#include "ui/aura/window.h" +#include "ui/views/widget/widget.h" #include "ui/wm/public/activation_client.h" namespace chrome { @@ -21,13 +22,20 @@ window->Init(ui::LAYER_TEXTURED); window->Show(); } - TestBrowserWindowAura* browser_window = new TestBrowserWindowAura(std::move(window)); new TestBrowserWindowOwner(browser_window); return browser_window->CreateBrowser(params); } +std::unique_ptr<Browser> CreateBrowserWithViewsTestWindowForParams( + const Browser::CreateParams& params, + aura::Window* parent) { + TestBrowserWindowViews* browser_window = new TestBrowserWindowViews(parent); + new TestBrowserWindowOwner(browser_window); + return browser_window->CreateBrowser(params); +} + } // namespace chrome TestBrowserWindowAura::TestBrowserWindowAura( @@ -77,3 +85,51 @@ browser_ = new Browser(*params); return base::WrapUnique(browser_); } + +TestBrowserWindowViews::TestBrowserWindowViews(aura::Window* parent) + : widget_(std::make_unique<views::Widget>()) { + views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); + params.bounds = gfx::Rect(5, 5, 20, 20); + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + params.parent = parent; + widget_->Init(params); +} + +TestBrowserWindowViews::~TestBrowserWindowViews() {} + +gfx::NativeWindow TestBrowserWindowViews::GetNativeWindow() const { + return widget_->GetNativeWindow(); +} + +void TestBrowserWindowViews::Show() { + widget_->Show(); +} + +void TestBrowserWindowViews::Hide() { + widget_->Hide(); +} + +bool TestBrowserWindowViews::IsVisible() const { + return widget_->IsVisible(); +} + +void TestBrowserWindowViews::Activate() { + widget_->Activate(); +} + +bool TestBrowserWindowViews::IsActive() const { + return widget_->IsActive(); +} + +gfx::Rect TestBrowserWindowViews::GetBounds() const { + return widget_->GetWindowBoundsInScreen(); +} + +std::unique_ptr<Browser> TestBrowserWindowViews::CreateBrowser( + const Browser::CreateParams& params) { + Browser::CreateParams params_copy = params; + params_copy.window = this; + std::unique_ptr<Browser> browser = std::make_unique<Browser>(params_copy); + browser_ = browser.get(); + return browser; +}
diff --git a/chrome/test/base/test_browser_window_aura.h b/chrome/test/base/test_browser_window_aura.h index 118577d..f7dcf71 100644 --- a/chrome/test/base/test_browser_window_aura.h +++ b/chrome/test/base/test_browser_window_aura.h
@@ -7,9 +7,16 @@ #include "base/macros.h" #include "chrome/test/base/test_browser_window.h" -#include "ui/aura/window.h" + +namespace aura { +class Window; +} +namespace views { +class Widget; +} // A browser window proxy with an associated Aura native window. +// TODO: replace this with TestBrowserWindowViews. class TestBrowserWindowAura : public TestBrowserWindow { public: explicit TestBrowserWindowAura(std::unique_ptr<aura::Window> native_window); @@ -33,6 +40,29 @@ DISALLOW_COPY_AND_ASSIGN(TestBrowserWindowAura); }; +class TestBrowserWindowViews : public TestBrowserWindow { + public: + explicit TestBrowserWindowViews(aura::Window* parent = nullptr); + ~TestBrowserWindowViews() override; + + // TestBrowserWindow overrides: + gfx::NativeWindow GetNativeWindow() const override; + void Show() override; + void Hide() override; + bool IsVisible() const override; + void Activate() override; + bool IsActive() const override; + gfx::Rect GetBounds() const override; + + std::unique_ptr<Browser> CreateBrowser(const Browser::CreateParams& params); + + private: + Browser* browser_; // not owned + std::unique_ptr<views::Widget> widget_; + + DISALLOW_COPY_AND_ASSIGN(TestBrowserWindowViews); +}; + namespace chrome { // Helper that creates a browser with a native Aura |window|. If |window| is @@ -42,6 +72,11 @@ std::unique_ptr<aura::Window> window, Browser::CreateParams* params); +// Helper that creates a browser with a Widget serving as the BrowserWindow. +std::unique_ptr<Browser> CreateBrowserWithViewsTestWindowForParams( + const Browser::CreateParams& params, + aura::Window* parent = nullptr); + } // namespace chrome #endif // CHROME_TEST_BASE_TEST_BROWSER_WINDOW_AURA_H_
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index d064d79..5548e4d 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -134,6 +134,11 @@ _OS_VERSION_SPECIFIC_FILTER = {} +_OS_VERSION_SPECIFIC_FILTER['mac', 'HEAD'] = [ + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2710 + 'ChromeDriverSiteIsolation.testCanClickOOPIF', +] + _DESKTOP_NEGATIVE_FILTER = [ # Desktop doesn't support touch (without --touch-events). 'ChromeDriverTest.testTouchSingleTapElement',
diff --git a/chrome/test/data/extensions/browsertest/title_localized/chrome-16.png b/chrome/test/data/extensions/browsertest/title_localized/chrome-16.png deleted file mode 100644 index a04372d..0000000 --- a/chrome/test/data/extensions/browsertest/title_localized/chrome-16.png +++ /dev/null Binary files differ
diff --git a/chrome/test/data/extensions/browsertest/title_localized/manifest.json b/chrome/test/data/extensions/browsertest/title_localized/manifest.json deleted file mode 100644 index 7eefdc6..0000000 --- a/chrome/test/data/extensions/browsertest/title_localized/manifest.json +++ /dev/null
@@ -1,11 +0,0 @@ -{ - "description": "Hreggvi\u00F0ur: l10n browser action", - "name": "Hreggvi\u00F0ur is my name", - "browser_action": { - "default_title": "Hreggvi\u00F0ur", - "default_icon": "chrome-16.png" - }, - "permissions": [ "http://*/*" ], - "manifest_version": 2, - "version": "1.0" -}
diff --git a/chrome/test/data/extensions/browsertest/title_localized_pa/background.js b/chrome/test/data/extensions/browsertest/title_localized_pa/background.js deleted file mode 100644 index 257d3e0b..0000000 --- a/chrome/test/data/extensions/browsertest/title_localized_pa/background.js +++ /dev/null
@@ -1,11 +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. - -chrome.runtime.onConnect.addListener(function(port) { - port.onMessage.addListener(function(mybool) { - // Let Chrome know that the PageAction needs to be enabled for this tabId - // and for the url of this page. - chrome.pageAction.show(port.sender.tab.id); - }); -});
diff --git a/chrome/test/data/extensions/browsertest/title_localized_pa/chrome-16.png b/chrome/test/data/extensions/browsertest/title_localized_pa/chrome-16.png deleted file mode 100644 index a04372d..0000000 --- a/chrome/test/data/extensions/browsertest/title_localized_pa/chrome-16.png +++ /dev/null Binary files differ
diff --git a/chrome/test/data/extensions/browsertest/title_localized_pa/manifest.json b/chrome/test/data/extensions/browsertest/title_localized_pa/manifest.json deleted file mode 100644 index 2388f298..0000000 --- a/chrome/test/data/extensions/browsertest/title_localized_pa/manifest.json +++ /dev/null
@@ -1,18 +0,0 @@ -{ - "background": { - "scripts": ["background.js"] - }, - "content_scripts": [ { - "js": [ "script.js" ], - "matches": [ "http://*/*" ] - } ], - "description": "Hreggvi\u00F0ur: l10n page action", - "name": "Hreggvi\u00F0ur is my name", - "page_action": { - "default_title": "Hreggvi\u00F0ur", - "default_icon": "chrome-16.png" - }, - "permissions": [ "http://*/*" ], - "manifest_version": 2, - "version": "1.0" -}
diff --git a/chrome/test/data/extensions/browsertest/title_localized_pa/script.js b/chrome/test/data/extensions/browsertest/title_localized_pa/script.js deleted file mode 100644 index 08bfee2..0000000 --- a/chrome/test/data/extensions/browsertest/title_localized_pa/script.js +++ /dev/null
@@ -1,7 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -if (window == top) { - chrome.runtime.connect().postMessage(true); -}
diff --git a/chrome/test/data/extensions/browsertest/title_localized_pa/simple.html b/chrome/test/data/extensions/browsertest/title_localized_pa/simple.html deleted file mode 100644 index 00061750..0000000 --- a/chrome/test/data/extensions/browsertest/title_localized_pa/simple.html +++ /dev/null
@@ -1,7 +0,0 @@ -<html> -<head> -</head> -<body> -This is a dead simple page. -</body> -</html> \ No newline at end of file
diff --git a/chrome/test/data/webui/app_management/reducers_test.js b/chrome/test/data/webui/app_management/reducers_test.js index 1ccafbe..a6fafb2 100644 --- a/chrome/test/data/webui/app_management/reducers_test.js +++ b/chrome/test/data/webui/app_management/reducers_test.js
@@ -5,6 +5,7 @@ suite('app state', function() { let apps; let action; + let state; function createApp(id, config) { return app_management.FakePageHandler.createApp(id, config); @@ -16,6 +17,12 @@ '1': createApp('1'), '2': createApp('2'), }; + + // Create an initial state. + state = app_management.util.createInitialState([ + createApp('1'), + createApp('2'), + ]); }); test('updates when apps are added', function() { @@ -45,12 +52,12 @@ action = app_management.actions.changeApp(changedApp); apps = app_management.AppState.updateApps(apps, action); - // Check that app has changed + // Check that app has changed. const app = apps['2']; assertEquals(1, app.type); assertEquals('a', app.title); - // Check that number of apps hasn't changed + // Check that number of apps hasn't changed. assertEquals(Object.keys(apps).length, 2); }); @@ -58,10 +65,48 @@ action = app_management.actions.removeApp('1'); apps = app_management.AppState.updateApps(apps, action); - // Check that app is removed + // Check that app is removed. assertFalse(!!apps['1']); - // Check that other app is unaffected + // Check that other app is unaffected. assertTrue(!!apps['2']); }); + + test('state updates when changing to main page', function() { + // Returning to main page results in no selected app. + state.currentPage.selectedAppId = '1'; + state.currentPage.pageType = PageType.DETAIL; + + action = app_management.actions.changePage(PageType.MAIN); + state = app_management.reduceAction(state, action); + + assertEquals(null, state.currentPage.selectedAppId); + assertEquals(PageType.MAIN, state.currentPage.pageType); + + // Id is disregarded when changing to main page. + action = app_management.actions.changePage(PageType.MAIN, '1'); + state = app_management.reduceAction(state, action); + + assertEquals(null, state.currentPage.selectedAppId); + assertEquals(PageType.MAIN, state.currentPage.pageType); + }); + + test('state updates when changing to app detail page', function() { + // State updates when a valid app detail page is selected. + action = app_management.actions.changePage(PageType.DETAIL, '2'); + state = app_management.reduceAction(state, action); + + assertEquals('2', state.currentPage.selectedAppId); + assertEquals(PageType.DETAIL, state.currentPage.pageType); + + // State returns to main page if invalid app id is given. + state.currentPage.selectedAppId = '2'; + state.currentPage.pageType = PageType.DETAIL; + + action = app_management.actions.changePage(PageType.DETAIL, '3'); + state = app_management.reduceAction(state, action); + + assertEquals(null, state.currentPage.selectedAppId); + assertEquals(PageType.MAIN, state.currentPage.pageType); + }); });
diff --git a/chrome/test/data/webui/extensions/activity_log_test.js b/chrome/test/data/webui/extensions/activity_log_test.js index e23443a..4adb5bc1 100644 --- a/chrome/test/data/webui/extensions/activity_log_test.js +++ b/chrome/test/data/webui/extensions/activity_log_test.js
@@ -98,6 +98,62 @@ expectEquals(activityLogItems[1].$$('#activity-count').innerText, '35'); }); + test('activities shown match search query', function() { + const search = activityLog.$$('cr-search-field'); + assertTrue(!!search); + + // Partial, case insensitive search for i18n.getUILanguage. Whitespace is + // also appended to the search term to test trimming. + search.setValue('getuilanguage '); + + return proxyDelegate.whenCalled('getFilteredExtensionActivityLog') + .then(() => { + Polymer.dom.flush(); + + const activityLogItems = + activityLog.shadowRoot.querySelectorAll('activity-log-item'); + + // Since we searched for an API call, we expect only one match as + // activity log entries are grouped by their API call. + expectEquals(activityLogItems.length, 1); + expectEquals( + activityLogItems[0].$$('#api-call').innerText, + 'i18n.getUILanguage'); + + // Change search query so no results match. + proxyDelegate.resetResolver('getFilteredExtensionActivityLog'); + search.setValue('query that does not match any activities'); + + return proxyDelegate.whenCalled('getFilteredExtensionActivityLog'); + }) + .then(() => { + Polymer.dom.flush(); + + testVisible('#no-activities', true); + testVisible('#loading-activities', false); + testVisible('#activity-list', false); + + expectEquals( + activityLog.shadowRoot.querySelectorAll('activity-log-item') + .length, + 0); + + proxyDelegate.resetResolver('getExtensionActivityLog'); + + // Finally, we clear the search query via the #clearSearch button. We + // should see all the activities displayed. + search.$$('#clearSearch').click(); + return proxyDelegate.whenCalled('getExtensionActivityLog'); + }) + .then(() => { + Polymer.dom.flush(); + + const activityLogItems = + activityLog.shadowRoot.querySelectorAll('activity-log-item'); + expectEquals(activityLogItems.length, 2); + }); + }); + test('message shown when no activities present for extension', function() { // Spoof an API call and pretend that the extension has no activities. activityLog.activityData_ = [];
diff --git a/chrome/test/data/webui/extensions/test_service.js b/chrome/test/data/webui/extensions/test_service.js index 36b6852..d341993 100644 --- a/chrome/test/data/webui/extensions/test_service.js +++ b/chrome/test/data/webui/extensions/test_service.js
@@ -11,6 +11,7 @@ 'getExtensionActivityLog', 'getExtensionsInfo', 'getExtensionSize', + 'getFilteredExtensionActivityLog', 'getProfileConfiguration', 'loadUnpacked', 'retryLoadUnpacked', @@ -159,6 +160,32 @@ this.methodCalled('getExtensionActivityLog', id); return Promise.resolve(this.testActivities); } + + /** @override */ + getFilteredExtensionActivityLog(id, searchTerm) { + // This is functionally identical to getFilteredExtensionActivityLog in + // service.js but we do the filtering here instead of making API calls + // with filter objects. + this.methodCalled('getFilteredExtensionActivityLog', id, searchTerm); + + // Convert everything to lowercase as searching is not case sensitive. + const lowerCaseSearchTerm = searchTerm.toLowerCase(); + + const activities = this.testActivities.activities; + const apiCallMatches = activities.filter( + activity => + activity.apiCall.toLowerCase().includes(lowerCaseSearchTerm)); + const pageUrlMatches = activities.filter( + activity => activity.pageUrl && + activity.pageUrl.toLowerCase().includes(lowerCaseSearchTerm)); + const argUrlMatches = activities.filter( + activity => activity.argUrl && + activity.argUrl.toLowerCase().includes(lowerCaseSearchTerm)); + + return Promise.resolve({ + activities: [...apiCallMatches, ...pageUrlMatches, ...argUrlMatches] + }); + } } return {
diff --git a/chrome/test/data/webui/settings/settings_main_test.js b/chrome/test/data/webui/settings/settings_main_test.js index 0f0095c..308611e 100644 --- a/chrome/test/data/webui/settings/settings_main_test.js +++ b/chrome/test/data/webui/settings/settings_main_test.js
@@ -322,5 +322,17 @@ assertFalse(basicPage.showChangePassword); assertFalse(!!basicPage.$$('settings-change-password-page')); }); + + test('updates the title based on current route', function() { + settings.navigateTo(settings.routes.BASIC); + assertEquals(document.title, loadTimeData.getString('settings')); + + settings.navigateTo(settings.routes.ABOUT); + assertEquals( + document.title, + loadTimeData.getStringF( + 'settingsAltPageTitle', + loadTimeData.getString('aboutPageTitle'))); + }); }); });
diff --git a/chrome/test/data/webui/settings/settings_subpage_test.js b/chrome/test/data/webui/settings/settings_subpage_test.js index bbf58027..3c84550 100644 --- a/chrome/test/data/webui/settings/settings_subpage_test.js +++ b/chrome/test/data/webui/settings/settings_subpage_test.js
@@ -67,6 +67,20 @@ done(); }); }); + + test('updates the title of the document when active', function() { + const expectedTitle = 'My Subpage Title'; + settings.navigateTo(settings.routes.SEARCH); + const subpage = document.createElement('settings-subpage'); + subpage.setAttribute('route-path', settings.routes.SEARCH_ENGINES.path); + subpage.setAttribute('page-title', expectedTitle); + document.body.appendChild(subpage); + + settings.navigateTo(settings.routes.SEARCH_ENGINES); + assertEquals( + document.title, + loadTimeData.getStringF('settingsAltPageTitle', expectedTitle)); + }); }); suite('SettingsSubpageSearch', function() {
diff --git a/chrome/test/mini_installer/chrome_helper.py b/chrome/test/mini_installer/chrome_helper.py index 7d027354..d6e2974 100644 --- a/chrome/test/mini_installer/chrome_helper.py +++ b/chrome/test/mini_installer/chrome_helper.py
@@ -83,7 +83,7 @@ (process.pid, len(chrome_processes), process.exe)) process.wait() # Check for stragglers and keep waiting until all are gone. - chrome_processes = GetChromeProcesses() + chrome_processes = GetChromeProcesses(chrome_path) def GetWindowHandles(process_ids):
diff --git a/chrome/test/mini_installer/test_chrome_with_chromedriver.py b/chrome/test/mini_installer/test_chrome_with_chromedriver.py index bd50572..d1706683 100644 --- a/chrome/test/mini_installer/test_chrome_with_chromedriver.py +++ b/chrome/test/mini_installer/test_chrome_with_chromedriver.py
@@ -114,6 +114,8 @@ driver.quit() chrome_helper.WaitForChromeExit(args.chrome_path) report_count = CollectCrashReports(user_data_dir, args.output_dir) + if report_count: + emit_log = True try: DeleteWithRetry(user_data_dir, shutil.rmtree) except: @@ -123,6 +125,10 @@ if emit_log: with open(log_file) as fh: logging.error(fh.read()) + if args.output_dir: + target = os.path.join(args.output_dir, os.path.basename(log_file)) + shutil.copyfile(log_file, target) + logging.error('Saved Chrome log to %s', target) DeleteWithRetry(log_file, os.remove) if report_count: raise Exception('Failing test due to %s crash reports found' %
diff --git a/chrome/test/ppapi/ppapi_filechooser_browsertest.cc b/chrome/test/ppapi/ppapi_filechooser_browsertest.cc index 96877d9..40b5c1e 100644 --- a/chrome/test/ppapi/ppapi_filechooser_browsertest.cc +++ b/chrome/test/ppapi/ppapi_filechooser_browsertest.cc
@@ -12,6 +12,7 @@ #include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/threading/thread_restrictions.h" +#include "build/build_config.h" #include "chrome/browser/safe_browsing/download_protection/download_protection_util.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/ppapi/ppapi_test.h" @@ -234,12 +235,17 @@ RunTestViaHTTP("FileChooser_SaveAsCancel"); } -#if defined(OS_WIN) || defined(OS_LINUX) +#if defined(OS_WIN) || defined(OS_LINUX) && !defined(OS_CHROMEOS) // On Windows, tests that a file downloaded via PPAPI FileChooser API has the // mark-of-the-web. The PPAPI FileChooser implementation invokes QuarantineFile // in order to mark the file as being downloaded from the web as soon as the // file is created. This MOTW prevents the file being opened without due // security warnings if the file is executable. +// +// On Linux Desktop, the setxattr call is made to set 'user.xdg.origin.url' and +// the non-standard 'user.xdg.referrer.url' extended attributes to accomplish +// the same thing. See +// https://www.freedesktop.org/wiki/CommonExtendedAttributes/. IN_PROC_BROWSER_TEST_F(PPAPIFileChooserTest, FileChooser_Quarantine) { base::ScopedAllowBlockingForTesting allow_blocking; base::ScopedTempDir temp_dir; @@ -259,7 +265,7 @@ ASSERT_TRUE(base::PathExists(actual_filename)); EXPECT_TRUE(download::IsFileQuarantined(actual_filename, GURL(), GURL())); } -#endif // defined(OS_WIN) || defined(OS_LINUX) +#endif // defined(OS_WIN) || defined(OS_LINUX) && !defined(OS_CHROMEOS) #if defined(FULL_SAFE_BROWSING) // These tests only make sense when SafeBrowsing is enabled. They verify
diff --git a/chromecast/base/cast_features.cc b/chromecast/base/cast_features.cc index df50c09..e426d1e 100644 --- a/chromecast/base/cast_features.cc +++ b/chromecast/base/cast_features.cc
@@ -181,7 +181,8 @@ const base::ListValue& dcs_experiment_ids, const std::string& cmd_line_enable_features, const std::string& cmd_line_disable_features, - const std::string& extra_enable_features) { + const std::string& extra_enable_features, + const std::string& extra_disable_features) { DCHECK(!base::FeatureList::GetInstance()); // Set the experiments. @@ -189,11 +190,13 @@ std::string all_enable_features = cmd_line_enable_features + "," + extra_enable_features; + std::string all_disable_features = + cmd_line_disable_features + "," + extra_disable_features; // Initialize the FeatureList from the command line. auto feature_list = std::make_unique<base::FeatureList>(); feature_list->InitializeFromCommandLine(all_enable_features, - cmd_line_disable_features); + all_disable_features); // Override defaults from the DCS config. for (Iterator it(dcs_features); !it.IsAtEnd(); it.Advance()) {
diff --git a/chromecast/base/cast_features.h b/chromecast/base/cast_features.h index 7fe59f1..e7b3a45 100644 --- a/chromecast/base/cast_features.h +++ b/chromecast/base/cast_features.h
@@ -50,7 +50,8 @@ const base::ListValue& dcs_experiment_ids, const std::string& cmd_line_enable_features, const std::string& cmd_line_disable_features, - const std::string& extra_enable_features); + const std::string& extra_enable_features, + const std::string& extra_disable_features); // Determine whether or not a feature is enabled. This replaces // base::FeatureList::IsEnabled for Cast builds.
diff --git a/chromecast/base/cast_features_unittest.cc b/chromecast/base/cast_features_unittest.cc index 186dfc5..aaa7ad0 100644 --- a/chromecast/base/cast_features_unittest.cc +++ b/chromecast/base/cast_features_unittest.cc
@@ -63,7 +63,7 @@ features->SetBoolean(kTestBooleanFeatureName3, true); features->SetBoolean(kTestBooleanFeatureName4, true); - InitializeFeatureList(*features, *experiments, "", "", ""); + InitializeFeatureList(*features, *experiments, "", "", "", ""); // Test that features are properly enabled (they should match the // DCS config). @@ -91,7 +91,7 @@ params->SetString("bool_key", "true"); features->Set(kTestParamsFeatureName, std::move(params)); - InitializeFeatureList(*features, *experiments, "", "", ""); + InitializeFeatureList(*features, *experiments, "", "", "", ""); // Test that this feature is enabled, and params are correct. ASSERT_TRUE(chromecast::IsFeatureEnabled(test_feature)); @@ -150,7 +150,7 @@ .append(kTestParamsFeatureName); InitializeFeatureList(*features, *experiments, enabled_features, - disabled_features, ""); + disabled_features, "", ""); // Test that features are properly enabled (they should match the // DCS config). @@ -170,7 +170,7 @@ auto experiments = std::make_unique<base::ListValue>(); auto features = std::make_unique<base::DictionaryValue>(); - InitializeFeatureList(*features, *experiments, "", "", ""); + InitializeFeatureList(*features, *experiments, "", "", "", ""); ASSERT_EQ(0u, GetDCSExperimentIds().size()); } @@ -186,7 +186,7 @@ expected.insert(id); } - InitializeFeatureList(*features, *experiments, "", "", ""); + InitializeFeatureList(*features, *experiments, "", "", "", ""); ASSERT_EQ(expected, GetDCSExperimentIds()); } @@ -204,7 +204,7 @@ expected.insert(1234); expected.insert(1); - InitializeFeatureList(*features, *experiments, "", "", ""); + InitializeFeatureList(*features, *experiments, "", "", "", ""); ASSERT_EQ(expected, GetDCSExperimentIds()); } @@ -218,7 +218,7 @@ std::unordered_set<int32_t> expected; - InitializeFeatureList(*features, *experiments, "", "", ""); + InitializeFeatureList(*features, *experiments, "", "", "", ""); ASSERT_EQ(expected, GetDCSExperimentIds()); }
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc index 0b2dca79..08b7e59 100644 --- a/chromecast/browser/cast_content_browser_client.cc +++ b/chromecast/browser/cast_content_browser_client.cc
@@ -73,6 +73,7 @@ #include "content/public/common/url_constants.h" #include "content/public/common/web_preferences.h" #include "media/audio/audio_thread_impl.h" +#include "media/base/media_switches.h" #include "media/mojo/buildflags.h" #include "net/ssl/ssl_cert_request_info.h" #include "net/url_request/url_request_context_getter.h" @@ -186,6 +187,12 @@ std::string(); #endif cast_feature_list_creator_->SetExtraEnableFeatures(extra_enable_features); + // TODO(mdellaquila): This feature has to be disabled because it causes + // significantly higher power consumption while flinging media files. + // Remove this after fixing the bug: b/111363899 + const std::string extra_disable_features = + ::media::kUseModernMediaControls.name; + cast_feature_list_creator_->SetExtraDisableFeatures(extra_disable_features); } CastContentBrowserClient::~CastContentBrowserClient() {
diff --git a/chromecast/browser/cast_feature_list_creator.cc b/chromecast/browser/cast_feature_list_creator.cc index 4eb0069..ca9c4b7 100644 --- a/chromecast/browser/cast_feature_list_creator.cc +++ b/chromecast/browser/cast_feature_list_creator.cc
@@ -38,7 +38,7 @@ *features_dict, *experiment_ids, command_line->GetSwitchValueASCII(switches::kEnableFeatures), command_line->GetSwitchValueASCII(switches::kDisableFeatures), - extra_enable_features_); + extra_enable_features_, extra_disable_features_); } std::unique_ptr<PrefService> CastFeatureListCreator::TakePrefService() { @@ -50,4 +50,9 @@ extra_enable_features_ = extra_enable_features; } +void CastFeatureListCreator::SetExtraDisableFeatures( + std::string extra_disable_features) { + extra_disable_features_ = extra_disable_features; +} + } // namespace chromecast
diff --git a/chromecast/browser/cast_feature_list_creator.h b/chromecast/browser/cast_feature_list_creator.h index 41cd3d83..4fc6026 100644 --- a/chromecast/browser/cast_feature_list_creator.h +++ b/chromecast/browser/cast_feature_list_creator.h
@@ -30,12 +30,17 @@ // Sets the extra features to be enabled. void SetExtraEnableFeatures(std::string extra_enable_features); + // Sets the extra features to be disabled. + void SetExtraDisableFeatures(std::string extra_disable_features); + private: // Holds the |PrefService| until TakePrefService() is called and ownership // is taken away. std::unique_ptr<PrefService> pref_service_; // Extra features that can be enabled at run time. std::string extra_enable_features_; + // Extra features that can be disabled at run time. + std::string extra_disable_features_; }; } // namespace chromecast
diff --git a/chromecast/browser/cast_media_blocker_unittest.cc b/chromecast/browser/cast_media_blocker_unittest.cc index b642959..f3a1170d5 100644 --- a/chromecast/browser/cast_media_blocker_unittest.cc +++ b/chromecast/browser/cast_media_blocker_unittest.cc
@@ -31,8 +31,6 @@ MOCK_METHOD1(Suspend, void(content::MediaSession::SuspendType)); MOCK_METHOD1(Stop, void(content::MediaSession::SuspendType)); MOCK_METHOD1(Seek, void(base::TimeDelta)); - MOCK_CONST_METHOD0(IsControllable, bool()); - MOCK_CONST_METHOD0(IsActuallyPaused, bool()); MOCK_METHOD0(StartDucking, void()); MOCK_METHOD0(StopDucking, void()); MOCK_METHOD1(SetDuckingVolumeMultiplier, void(double));
diff --git a/chromecast/media/audio/cast_audio_manager.cc b/chromecast/media/audio/cast_audio_manager.cc index 793622e6..3cd6f88 100644 --- a/chromecast/media/audio/cast_audio_manager.cc +++ b/chromecast/media/audio/cast_audio_manager.cc
@@ -94,6 +94,15 @@ return true; } +void CastAudioManager::GetAudioOutputDeviceNames( + ::media::AudioDeviceNames* device_names) { + DCHECK(device_names->empty()); + if (HasAudioOutputDevices()) { + device_names->push_front(::media::AudioDeviceName::CreateCommunications()); + device_names->push_front(::media::AudioDeviceName::CreateDefault()); + } +} + bool CastAudioManager::HasAudioInputDevices() { return false; } @@ -150,28 +159,32 @@ // If |mixer_| exists, return a mixing stream. if (mixer_) { - return mixer_->MakeStream(params, ""); + return mixer_->MakeStream(params); } else { return new CastAudioOutputStream( - this, GetConnector(), params, "", + this, GetConnector(), params, + ::media::AudioDeviceDescription::kDefaultDeviceId, GetMixerServiceConnectionFactoryForOutputStream(params)); } } ::media::AudioOutputStream* CastAudioManager::MakeLowLatencyOutputStream( const ::media::AudioParameters& params, - const std::string& device_id, + const std::string& device_id_or_group_id, const ::media::AudioManager::LogCallback& log_callback) { DCHECK_EQ(::media::AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); - // If |mixer_| exists, return a mixing stream. + // If |mixer_| exists, return a mixing stream. If used, the mixing stream + // will use the default device_id, not |device_id_or_group_id| if (mixer_) { - return mixer_->MakeStream(params, device_id); + DCHECK(device_id_or_group_id.empty()); + return mixer_->MakeStream(params); } else { - // We use device_id as the group_id, because for Chromecast builds they are - // one and the same. See the header for more information. return new CastAudioOutputStream( - this, GetConnector(), params, device_id, + this, GetConnector(), params, + device_id_or_group_id.empty() + ? ::media::AudioDeviceDescription::kDefaultDeviceId + : device_id_or_group_id, GetMixerServiceConnectionFactoryForOutputStream(params)); } } @@ -230,18 +243,15 @@ } ::media::AudioOutputStream* CastAudioManager::MakeMixerOutputStream( - const ::media::AudioParameters& params, - const std::string& device_id) { + const ::media::AudioParameters& params) { DCHECK(mixer_); DCHECK(!mixer_output_stream_); // Only allow 1 |mixer_output_stream_|. // Keep a reference to this stream for proper behavior on // CastAudioManager::ReleaseOutputStream. - // - // We use device_id as the group_id, because for Chromecast builds they are - // one and the same. See the header for more information. mixer_output_stream_.reset(new CastAudioOutputStream( - this, GetConnector(), params, device_id, + this, GetConnector(), params, + ::media::AudioDeviceDescription::kDefaultDeviceId, GetMixerServiceConnectionFactoryForOutputStream(params))); return mixer_output_stream_.get(); }
diff --git a/chromecast/media/audio/cast_audio_manager.h b/chromecast/media/audio/cast_audio_manager.h index 1937cfb..fbecbdf 100644 --- a/chromecast/media/audio/cast_audio_manager.h +++ b/chromecast/media/audio/cast_audio_manager.h
@@ -16,18 +16,21 @@ #include "services/service_manager/public/cpp/connector.h" // NOTE: CastAudioManager receives a |device_id| from the audio service, and -// passes it to CastAudioOutputStream as a |group_id|. +// passes it to CastAudioOutputStream as a |device_id_or_group_id|. // -// The output stream requires the |group_id| so that it can determine the Cast -// |session_id| from CastSessionIdMap and pass it to CMA for multizone audio. -// The output stream does not require a real |device_id|, so we have repurposed -// the field for Cast devices only, in order to pass the |group_id| through all -// the layers of the audio stack into the CastAudioOutputStream. +// The output stream interprets the |device_id_or_group_id| as a device_id if it +// the value matches a valid device_id, either kCommunicationsDeviceId or +// kDefaultDeviceId (or an empty string as kDefaultDeviceId). If +// |device_id_or_group_id| does not match a valid device_id, then it is +// interpreted as a group_id. group_id is used to determine the |session_id| +// from CastSessionIdMap. Multizone audio is only enabled for kDefaultDeviceId +// so the correct device_id can be inferred without conflict. |group_id| are +// uuid. // // At the top end of the audio stack, StreamFactory replaces the |device_id| -// with the |group_id|. This implementation in StreamFactory must stay as-is, or -// else multizone audio will be broken for Cast devices using CAOS for their -// primary audio playback. +// with the |group_id| if the |group_id| is not empty. This implementation in +// StreamFactory is required for multizone audio for Cast devices using CAOS for +// their primary audio playback. namespace chromecast { @@ -56,6 +59,8 @@ // AudioManagerBase implementation. bool HasAudioOutputDevices() override; + void GetAudioOutputDeviceNames( + ::media::AudioDeviceNames* device_names) override; bool HasAudioInputDevices() override; void GetAudioInputDeviceNames( ::media::AudioDeviceNames* device_names) override; @@ -81,7 +86,7 @@ const ::media::AudioManager::LogCallback& log_callback) override; ::media::AudioOutputStream* MakeLowLatencyOutputStream( const ::media::AudioParameters& params, - const std::string& device_id, + const std::string& device_id_or_group_id, const ::media::AudioManager::LogCallback& log_callback) override; ::media::AudioOutputStream* MakeBitstreamOutputStream( const ::media::AudioParameters& params, @@ -101,8 +106,7 @@ // Generates a CastAudioOutputStream for |mixer_|. virtual ::media::AudioOutputStream* MakeMixerOutputStream( - const ::media::AudioParameters& params, - const std::string& device_id); + const ::media::AudioParameters& params); private: friend class CastAudioMixer;
diff --git a/chromecast/media/audio/cast_audio_manager_alsa_unittest.cc b/chromecast/media/audio/cast_audio_manager_alsa_unittest.cc index 3a440af..11b8a74 100644 --- a/chromecast/media/audio/cast_audio_manager_alsa_unittest.cc +++ b/chromecast/media/audio/cast_audio_manager_alsa_unittest.cc
@@ -35,7 +35,7 @@ return service_manager::Connector::Create(&request); } -std::string DummyGetSessionId(base::UnguessableToken /* audio_group_id */) { +std::string DummyGetSessionId(std::string /* audio_group_id */) { return ""; }
diff --git a/chromecast/media/audio/cast_audio_manager_unittest.cc b/chromecast/media/audio/cast_audio_manager_unittest.cc index 2a9431f2..369384a3 100644 --- a/chromecast/media/audio/cast_audio_manager_unittest.cc +++ b/chromecast/media/audio/cast_audio_manager_unittest.cc
@@ -274,5 +274,26 @@ stream->Close(); } +TEST_F(CastAudioManagerTest, CanMakeCommunicationsStream) { + CreateAudioManagerForTesting(); + SetUpBackendAndDecoder(); + + ::media::AudioOutputStream* stream = audio_manager_->MakeAudioOutputStream( + kDefaultAudioParams, + ::media::AudioDeviceDescription::kCommunicationsDeviceId, + ::media::AudioManager::LogCallback()); + EXPECT_TRUE(stream->Open()); + + EXPECT_CALL(mock_source_callback_, OnMoreData(_, _, _, _)) + .WillRepeatedly(Invoke(OnMoreData)); + EXPECT_CALL(mock_source_callback_, OnError()).Times(0); + scoped_task_environment_.RunUntilIdle(); + + stream->Stop(); + scoped_task_environment_.RunUntilIdle(); + + stream->Close(); +} + } // namespace media } // namespace chromecast
diff --git a/chromecast/media/audio/cast_audio_mixer.cc b/chromecast/media/audio/cast_audio_mixer.cc index fe7c7dc..0b9884eb 100644 --- a/chromecast/media/audio/cast_audio_mixer.cc +++ b/chromecast/media/audio/cast_audio_mixer.cc
@@ -26,12 +26,10 @@ public: MixerProxyStream(const ::media::AudioParameters& input_params, const ::media::AudioParameters& output_params, - const std::string& device_id, CastAudioMixer* audio_mixer) : audio_mixer_(audio_mixer), input_params_(input_params), output_params_(output_params), - device_id_(device_id), opened_(false), volume_(1.0), source_callback_(nullptr) { @@ -98,7 +96,7 @@ DCHECK_GE(input_params_.channels(), 1); DCHECK_LE(input_params_.channels(), 2); - return opened_ = audio_mixer_->Register(this, device_id_); + return opened_ = audio_mixer_->Register(this); } void Close() override { @@ -170,7 +168,6 @@ CastAudioMixer* const audio_mixer_; const ::media::AudioParameters input_params_; const ::media::AudioParameters output_params_; - const std::string device_id_; bool opened_; double volume_; @@ -195,14 +192,12 @@ CastAudioMixer::~CastAudioMixer() {} ::media::AudioOutputStream* CastAudioMixer::MakeStream( - const ::media::AudioParameters& params, - const std::string& device_id) { + const ::media::AudioParameters& params) { DCHECK_CALLED_ON_VALID_THREAD(audio_thread_checker_); - return new MixerProxyStream(params, output_params_, device_id, this); + return new MixerProxyStream(params, output_params_, this); } -bool CastAudioMixer::Register(MixerProxyStream* proxy_stream, - const std::string& device_id) { +bool CastAudioMixer::Register(MixerProxyStream* proxy_stream) { DCHECK_CALLED_ON_VALID_THREAD(audio_thread_checker_); DCHECK(!base::ContainsKey(proxy_streams_, proxy_stream)); @@ -215,8 +210,7 @@ // is not opened properly. if (proxy_streams_.empty()) { DCHECK(!output_stream_); - output_stream_ = - audio_manager_->MakeMixerOutputStream(output_params_, device_id); + output_stream_ = audio_manager_->MakeMixerOutputStream(output_params_); if (!output_stream_->Open()) { output_stream_->Close(); output_stream_ = nullptr;
diff --git a/chromecast/media/audio/cast_audio_mixer.h b/chromecast/media/audio/cast_audio_mixer.h index 16ea978..0a67090 100644 --- a/chromecast/media/audio/cast_audio_mixer.h +++ b/chromecast/media/audio/cast_audio_mixer.h
@@ -29,8 +29,7 @@ ~CastAudioMixer() override; virtual ::media::AudioOutputStream* MakeStream( - const ::media::AudioParameters& params, - const std::string& device_id); + const ::media::AudioParameters& params); private: class MixerProxyStream; @@ -43,7 +42,7 @@ void OnError() override; // MixedAudioOutputStreams call Register on opening and AddInput on starting. - bool Register(MixerProxyStream* proxy_stream, const std::string& device_id); + bool Register(MixerProxyStream* proxy_stream); void Unregister(MixerProxyStream* proxy_stream); void AddInput(::media::AudioConverter::InputCallback* input_callback); void RemoveInput(::media::AudioConverter::InputCallback* input_callback);
diff --git a/chromecast/media/audio/cast_audio_mixer_unittest.cc b/chromecast/media/audio/cast_audio_mixer_unittest.cc index c3dc7a3..8c090a86 100644 --- a/chromecast/media/audio/cast_audio_mixer_unittest.cc +++ b/chromecast/media/audio/cast_audio_mixer_unittest.cc
@@ -124,10 +124,9 @@ } media::CmaBackendFactory* GetCmaBackendFactory() { return nullptr; } - MOCK_METHOD2( + MOCK_METHOD1( MakeMixerOutputStream, - ::media::AudioOutputStream*(const ::media::AudioParameters& params, - const std::string& device_id)); + ::media::AudioOutputStream*(const ::media::AudioParameters& params)); MOCK_METHOD1(ReleaseOutputStream, void(::media::AudioOutputStream* stream)); private: @@ -152,7 +151,7 @@ connector_.get(), scoped_task_environment_.GetMainThreadTaskRunner())); mock_mixer_stream_.reset(new StrictMock<MockMediaAudioOutputStream>()); - ON_CALL(*mock_manager_, MakeMixerOutputStream(_, _)) + ON_CALL(*mock_manager_, MakeMixerOutputStream(_)) .WillByDefault(Return(mock_mixer_stream_.get())); ON_CALL(*mock_mixer_stream_, Start(_)) .WillByDefault(SaveArg<0>(&source_callback_)); @@ -201,7 +200,7 @@ ::media::AudioOutputStream* stream = CreateMixerStream(); ASSERT_TRUE(stream); - EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_, _)) + EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) .WillOnce(Return(&mock_mixer_stream())); EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(false)); EXPECT_CALL(mock_mixer_stream(), Close()); @@ -227,7 +226,7 @@ stream->Stop(); stream->Start(&source); - EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_, _)) + EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) .WillOnce(Return(&mock_mixer_stream())); EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(false)); EXPECT_CALL(mock_mixer_stream(), Close()); @@ -237,7 +236,7 @@ stream->Start(&source); stream->Stop(); - EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_, _)) + EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) .WillOnce(Return(&mock_mixer_stream())); EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); ASSERT_TRUE(stream->Open()); @@ -257,7 +256,7 @@ ::media::AudioOutputStream* stream = CreateMixerStream(); ASSERT_TRUE(stream); - EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_, _)) + EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) .WillOnce(Return(&mock_mixer_stream())); EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); ASSERT_TRUE(stream->Open()); @@ -285,7 +284,7 @@ new StrictMock<MockAudioSourceCallback>()); }); - EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_, _)) + EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) .WillOnce(Return(&mock_mixer_stream())); EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); for (auto* stream : streams) @@ -326,7 +325,7 @@ ASSERT_TRUE(stream1); ASSERT_TRUE(stream2); - EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_, _)) + EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) .WillOnce(Return(&mock_mixer_stream())); EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); ASSERT_TRUE(stream1->Open()); @@ -355,7 +354,7 @@ for (auto* stream : streams) ASSERT_TRUE(stream); - EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_, _)) + EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) .WillOnce(Return(&mock_mixer_stream())); EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); for (auto* stream : streams) @@ -385,7 +384,7 @@ // Now that the state has been refreshed, attempt to open a stream. streams.push_back(CreateMixerStream()); - EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_, _)) + EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) .WillOnce(Return(&mock_mixer_stream())); EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); ASSERT_TRUE(streams.front()->Open()); @@ -403,7 +402,7 @@ MockAudioSourceCallback source; ::media::AudioOutputStream* stream = CreateMixerStream(); - EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_, _)) + EXPECT_CALL(mock_manager(), MakeMixerOutputStream(_)) .WillOnce(Return(&mock_mixer_stream())); EXPECT_CALL(mock_mixer_stream(), Open()).WillOnce(Return(true)); ASSERT_TRUE(stream->Open());
diff --git a/chromecast/media/audio/cast_audio_output_stream.cc b/chromecast/media/audio/cast_audio_output_stream.cc index 389598c1..b2542a1 100644 --- a/chromecast/media/audio/cast_audio_output_stream.cc +++ b/chromecast/media/audio/cast_audio_output_stream.cc
@@ -60,11 +60,40 @@ namespace chromecast { namespace media { +namespace { + +AudioContentType GetContentType(const std::string& device_id) { + if (::media::AudioDeviceDescription::IsCommunicationsDevice(device_id)) { + return AudioContentType::kCommunication; + } + return AudioContentType::kMedia; +} + +mixer_service::MixerStreamParams::ContentType ConvertContentType( + AudioContentType content_type) { + switch (content_type) { + case AudioContentType::kMedia: + return mixer_service::MixerStreamParams::CONTENT_TYPE_MEDIA; + case AudioContentType::kCommunication: + return mixer_service::MixerStreamParams::CONTENT_TYPE_COMMUNICATION; + default: + NOTREACHED(); + return mixer_service::MixerStreamParams::CONTENT_TYPE_MEDIA; + } +} + +bool IsValidDeviceId(const std::string& device_id) { + return ::media::AudioDeviceDescription::IsCommunicationsDevice(device_id) || + device_id == ::media::AudioDeviceDescription::kDefaultDeviceId; +} + +} // namespace class CastAudioOutputStream::CmaWrapper : public CmaBackend::Decoder::Delegate { public: CmaWrapper(scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, const ::media::AudioParameters& audio_params, + const std::string& device_id, CmaBackendFactory* cma_backend_factory); void Initialize(const std::string& application_session_id, @@ -88,6 +117,7 @@ scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_; const ::media::AudioParameters audio_params_; + const std::string device_id_; CmaBackendFactory* const cma_backend_factory_; AudioOutputState media_thread_state_; @@ -112,9 +142,11 @@ CastAudioOutputStream::CmaWrapper::CmaWrapper( scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, const ::media::AudioParameters& audio_params, + const std::string& device_id, CmaBackendFactory* cma_backend_factory) : audio_task_runner_(audio_task_runner), audio_params_(audio_params), + device_id_(device_id), cma_backend_factory_(cma_backend_factory), media_thread_state_(kClosed), timestamp_helper_(audio_params_.sample_rate()), @@ -122,6 +154,7 @@ DETACH_FROM_THREAD(media_thread_checker_); DCHECK(audio_task_runner_); DCHECK(cma_backend_factory_); + DCHECK(IsValidDeviceId(device_id)); // Set the default state. push_in_progress_ = false; @@ -149,8 +182,7 @@ cma_backend_task_runner_ = std::make_unique<TaskRunnerImpl>(); MediaPipelineDeviceParams device_params( MediaPipelineDeviceParams::kModeIgnorePts, stream_type, - cma_backend_task_runner_.get(), AudioContentType::kMedia, - ::media::AudioDeviceDescription::kDefaultDeviceId); + cma_backend_task_runner_.get(), GetContentType(device_id_), device_id_); device_params.session_id = application_session_id; device_params.multiroom = multiroom_info->multiroom; device_params.audio_channel = multiroom_info->audio_channel; @@ -342,6 +374,7 @@ public: MixerServiceWrapper( const ::media::AudioParameters& audio_params, + const std::string& device_id, MixerServiceConnectionFactory* mixer_service_connection_factory); ~MixerServiceWrapper() override = default; @@ -364,6 +397,7 @@ void OnEosPlayed() override { NOTREACHED(); } const ::media::AudioParameters audio_params_; + const std::string device_id_; MixerServiceConnectionFactory* mixer_service_connection_factory_; std::unique_ptr<::media::AudioBus> audio_bus_; AudioSourceCallback* source_callback_; @@ -381,14 +415,17 @@ CastAudioOutputStream::MixerServiceWrapper::MixerServiceWrapper( const ::media::AudioParameters& audio_params, + const std::string& device_id, MixerServiceConnectionFactory* mixer_service_connection_factory) : audio_params_(audio_params), + device_id_(device_id), mixer_service_connection_factory_(mixer_service_connection_factory), source_callback_(nullptr), volume_(1.0f), io_thread_("CastAudioOutputStream IO") { DCHECK(mixer_service_connection_factory_); DETACH_FROM_THREAD(io_thread_checker_); + DCHECK(IsValidDeviceId(device_id)); base::Thread::Options options; options.message_loop_type = base::MessageLoop::TYPE_IO; @@ -403,13 +440,12 @@ DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); media::mixer_service::MixerStreamParams params; + params.set_content_type(ConvertContentType(GetContentType(device_id_))); + params.set_device_id(device_id_); params.set_stream_type( media::mixer_service::MixerStreamParams::STREAM_TYPE_SFX); - params.set_content_type( - media::mixer_service::MixerStreamParams::CONTENT_TYPE_MEDIA); params.set_sample_format( media::mixer_service::MixerStreamParams::SAMPLE_FORMAT_FLOAT_P); - params.set_device_id(::media::AudioDeviceDescription::kDefaultDeviceId); params.set_sample_rate(audio_params_.sample_rate()); params.set_num_channels(audio_params_.channels()); int64_t start_threshold_frames = ::media::AudioTimestampHelper::TimeToFrames( @@ -496,20 +532,25 @@ CastAudioManager* audio_manager, service_manager::Connector* connector, const ::media::AudioParameters& audio_params, - const std::string& group_id, + const std::string& device_id_or_group_id, MixerServiceConnectionFactory* mixer_service_connection_factory) : volume_(1.0), audio_thread_state_(kClosed), audio_manager_(audio_manager), connector_(connector), audio_params_(audio_params), - group_id_(group_id), + device_id_(::media::AudioDeviceDescription::IsCommunicationsDevice( + device_id_or_group_id) + ? ::media::AudioDeviceDescription::kCommunicationsDeviceId + : ::media::AudioDeviceDescription::kDefaultDeviceId), + group_id_(IsValidDeviceId(device_id_or_group_id) ? "" + : device_id_or_group_id), mixer_service_connection_factory_(mixer_service_connection_factory), audio_weak_factory_(this) { DCHECK(audio_manager_); DCHECK(connector_); DETACH_FROM_THREAD(audio_thread_checker_); - VLOG(1) << __func__ << " " << this << " created from group_id=" << group_id + VLOG(1) << __func__ << " " << this << " created from group_id=" << group_id_ << " with audio_params=" << audio_params_.AsHumanReadableString(); } @@ -682,7 +723,7 @@ if (!mixer_service_connection_factory_) { cma_wrapper_ = std::make_unique<CmaWrapper>( - audio_manager_->GetTaskRunner(), audio_params_, + audio_manager_->GetTaskRunner(), audio_params_, device_id_, audio_manager_->cma_backend_factory()); POST_TO_CMA_WRAPPER(Initialize, application_session_id, std::move(multiroom_info)); @@ -695,7 +736,7 @@ CastMediaShlib::AddDirectAudioSource); mixer_service_wrapper_ = std::make_unique<MixerServiceWrapper>( - audio_params_, mixer_service_connection_factory_); + audio_params_, device_id_, mixer_service_connection_factory_); } if (pending_start_)
diff --git a/chromecast/media/audio/cast_audio_output_stream.h b/chromecast/media/audio/cast_audio_output_stream.h index 1265b21..731d39f 100644 --- a/chromecast/media/audio/cast_audio_output_stream.h +++ b/chromecast/media/audio/cast_audio_output_stream.h
@@ -102,11 +102,18 @@ public: // When nullptr is passed as |mixer_service_connection_factory|, CmaWrapper // will be used for audio playback. + // |device_id_or_group_id| describes either the |device_id_| or |group_id_|. + // If the |device_id_or_group_id| matches a valid device_id then the + // |group_id_| is filled in empty. If the |device_id_or_group_id_| does not + // match a valid |device_id|, then the |group_id_| is set to that value, and + // the |device_id_| is set to kDefaultDeviceId. Valid device_id's are either + // ::media::AudioDeviceDescription::kDefaultDeviceId or + // ::media::AudioDeviceDescription::kCommunicationsId. CastAudioOutputStream( CastAudioManager* audio_manager, service_manager::Connector* connector, const ::media::AudioParameters& audio_params, - const std::string& group_id, + const std::string& device_id_or_group_id, MixerServiceConnectionFactory* mixer_service_connection_factory); ~CastAudioOutputStream() override; @@ -133,6 +140,10 @@ CastAudioManager* const audio_manager_; service_manager::Connector* connector_; const ::media::AudioParameters audio_params_; + // Valid |device_id_| are kDefaultDeviceId, and kCommunicationsDeviceId + const std::string device_id_; + // |group_id_|s are uuids mapped to session_ids for multizone. Should be an + // empty string if group_id is unused. const std::string group_id_; MixerServiceConnectionFactory* mixer_service_connection_factory_; chromecast::mojom::MultiroomManagerPtr multiroom_manager_;
diff --git a/chromecast/media/audio/cast_audio_output_stream_unittest.cc b/chromecast/media/audio/cast_audio_output_stream_unittest.cc index 3701ea6..eaead526 100644 --- a/chromecast/media/audio/cast_audio_output_stream_unittest.cc +++ b/chromecast/media/audio/cast_audio_output_stream_unittest.cc
@@ -23,6 +23,7 @@ #include "chromecast/media/cma/test/mock_cma_backend_factory.h" #include "chromecast/media/cma/test/mock_multiroom_manager.h" #include "chromecast/public/task_runner.h" +#include "chromecast/public/volume_control.h" #include "content/public/test/test_browser_thread.h" #include "content/public/test/test_browser_thread_bundle.h" #include "media/audio/mock_audio_source_callback.h" @@ -881,7 +882,9 @@ } TEST_F(CastAudioOutputStreamTest, SessionId) { - ::media::AudioOutputStream* stream = CreateStream(); + format_ = ::media::AudioParameters::AUDIO_PCM_LOW_LATENCY; + ::media::AudioOutputStream* stream = audio_manager_->MakeAudioOutputStream( + GetAudioParams(), "DummyGroupId", ::media::AudioManager::LogCallback()); ASSERT_TRUE(stream); ASSERT_TRUE(stream->Open()); RunThreadsUntilIdle(); @@ -908,5 +911,25 @@ stream->Close(); } +TEST_F(CastAudioOutputStreamTest, CommunicationsDeviceId) { + format_ = ::media::AudioParameters::AUDIO_PCM_LOW_LATENCY; + ::media::AudioOutputStream* stream = audio_manager_->MakeAudioOutputStream( + GetAudioParams(), + ::media::AudioDeviceDescription::kCommunicationsDeviceId, + ::media::AudioManager::LogCallback()); + ASSERT_TRUE(stream); + ASSERT_TRUE(stream->Open()); + RunThreadsUntilIdle(); + + ASSERT_TRUE(cma_backend_); + MediaPipelineDeviceParams params = cma_backend_->params(); + EXPECT_EQ(params.content_type, AudioContentType::kCommunication); + EXPECT_EQ(params.device_id, + ::media::AudioDeviceDescription::kCommunicationsDeviceId); + + stream->Stop(); + stream->Close(); +} + } // namespace media } // namespace chromecast
diff --git a/chromecast/media/cma/backend/alsa/alsa_wrapper.cc b/chromecast/media/cma/backend/alsa/alsa_wrapper.cc index ce86663..112b032 100644 --- a/chromecast/media/cma/backend/alsa/alsa_wrapper.cc +++ b/chromecast/media/cma/backend/alsa/alsa_wrapper.cc
@@ -46,10 +46,6 @@ return snd_pcm_status_get_avail(obj); } -ssize_t AlsaWrapper::PcmFormatSize(snd_pcm_format_t format, size_t samples) { - return snd_pcm_format_size(format, samples); -} - void AlsaWrapper::PcmStatusGetHtstamp(const snd_pcm_status_t* obj, snd_htimestamp_t* ptr) { snd_pcm_status_get_htstamp(obj, ptr); @@ -59,14 +55,6 @@ return snd_pcm_status_get_state(obj); } -int AlsaWrapper::PcmHwParamsMalloc(snd_pcm_hw_params_t** ptr) { - return snd_pcm_hw_params_malloc(ptr); -} - -void AlsaWrapper::PcmHwParamsFree(snd_pcm_hw_params_t* obj) { - snd_pcm_hw_params_free(obj); -} - int AlsaWrapper::PcmHwParamsCurrent(snd_pcm_t* handle, snd_pcm_hw_params_t* params) { return snd_pcm_hw_params_current(handle, params); @@ -76,56 +64,6 @@ return snd_pcm_hw_params_can_pause(params); } -int AlsaWrapper::PcmHwParamsSetRateResample(snd_pcm_t* handle, - snd_pcm_hw_params_t* params, - bool val) { - return snd_pcm_hw_params_set_rate_resample(handle, params, val); -} - -int AlsaWrapper::PcmHwParamsSetAccess(snd_pcm_t* handle, - snd_pcm_hw_params_t* params, - snd_pcm_access_t access) { - return snd_pcm_hw_params_set_access(handle, params, access); -} - -int AlsaWrapper::PcmHwParamsSetFormat(snd_pcm_t* handle, - snd_pcm_hw_params_t* params, - snd_pcm_format_t format) { - return snd_pcm_hw_params_set_format(handle, params, format); -} - -int AlsaWrapper::PcmHwParamsSetChannels(snd_pcm_t* handle, - snd_pcm_hw_params_t* params, - unsigned int num_channels) { - return snd_pcm_hw_params_set_channels(handle, params, num_channels); -} - -int AlsaWrapper::PcmHwParamsSetRateNear(snd_pcm_t* handle, - snd_pcm_hw_params_t* params, - unsigned int* rate, - int* dir) { - return snd_pcm_hw_params_set_rate_near(handle, params, rate, dir); -} - -int AlsaWrapper::PcmHwParamsSetBufferSizeNear(snd_pcm_t* handle, - snd_pcm_hw_params_t* params, - snd_pcm_uframes_t* val) { - return snd_pcm_hw_params_set_buffer_size_near(handle, params, val); -} - -int AlsaWrapper::PcmHwParamsSetPeriodSizeNear(snd_pcm_t* handle, - snd_pcm_hw_params_t* params, - snd_pcm_uframes_t* val, - int* dir) { - return snd_pcm_hw_params_set_period_size_near(handle, params, val, dir); -} - -int AlsaWrapper::PcmHwParamsTestFormat(snd_pcm_t* handle, - snd_pcm_hw_params_t* params, - snd_pcm_format_t format) { - return snd_pcm_hw_params_test_format(handle, params, format); -} - int AlsaWrapper::PcmHwParamsTestRate(snd_pcm_t* handle, snd_pcm_hw_params_t* params, unsigned int rate, @@ -133,40 +71,6 @@ return snd_pcm_hw_params_test_rate(handle, params, rate, dir); } -int AlsaWrapper::PcmHwParamsAny(snd_pcm_t* handle, - snd_pcm_hw_params_t* params) { - return snd_pcm_hw_params_any(handle, params); -} - -int AlsaWrapper::PcmHwParams(snd_pcm_t* handle, snd_pcm_hw_params_t* params) { - return snd_pcm_hw_params(handle, params); -} - -int AlsaWrapper::PcmSwParamsMalloc(snd_pcm_sw_params_t** params) { - return snd_pcm_sw_params_malloc(params); -} - -void AlsaWrapper::PcmSwParamsFree(snd_pcm_sw_params_t* params) { - snd_pcm_sw_params_free(params); -} - -int AlsaWrapper::PcmSwParamsCurrent(snd_pcm_t* handle, - snd_pcm_sw_params_t* params) { - return snd_pcm_sw_params_current(handle, params); -} - -int AlsaWrapper::PcmSwParamsSetStartThreshold(snd_pcm_t* handle, - snd_pcm_sw_params_t* params, - snd_pcm_uframes_t val) { - return snd_pcm_sw_params_set_start_threshold(handle, params, val); -} - -int AlsaWrapper::PcmSwParamsSetAvailMin(snd_pcm_t* handle, - snd_pcm_sw_params_t* params, - snd_pcm_uframes_t val) { - return snd_pcm_sw_params_set_avail_min(handle, params, val); -} - int AlsaWrapper::PcmSwParamsSetTstampMode(snd_pcm_t* handle, snd_pcm_sw_params_t* obj, snd_pcm_tstamp_t val) { @@ -184,9 +88,5 @@ #endif // BUILDFLAG(MEDIA_CLOCK_MONOTONIC_RAW) } -int AlsaWrapper::PcmSwParams(snd_pcm_t* handle, snd_pcm_sw_params_t* params) { - return snd_pcm_sw_params(handle, params); -} - } // namespace media } // namespace chromecast
diff --git a/chromecast/media/cma/backend/alsa/alsa_wrapper.h b/chromecast/media/cma/backend/alsa/alsa_wrapper.h index 97ca9bd..eeb0d88 100644 --- a/chromecast/media/cma/backend/alsa/alsa_wrapper.h +++ b/chromecast/media/cma/backend/alsa/alsa_wrapper.h
@@ -29,62 +29,20 @@ virtual void PcmStatusGetHtstamp(const snd_pcm_status_t* obj, snd_htimestamp_t* ptr); virtual snd_pcm_state_t PcmStatusGetState(const snd_pcm_status_t* obj); - virtual ssize_t PcmFormatSize(snd_pcm_format_t format, size_t samples); - virtual int PcmHwParamsMalloc(snd_pcm_hw_params_t** ptr); - virtual void PcmHwParamsFree(snd_pcm_hw_params_t* obj); virtual int PcmHwParamsCurrent(snd_pcm_t* handle, snd_pcm_hw_params_t* params); virtual int PcmHwParamsCanPause(const snd_pcm_hw_params_t* params); - virtual int PcmHwParamsAny(snd_pcm_t* handle, snd_pcm_hw_params_t* params); - virtual int PcmHwParamsSetRateResample(snd_pcm_t* handle, - snd_pcm_hw_params_t* params, - bool val); - virtual int PcmHwParamsSetAccess(snd_pcm_t* handle, - snd_pcm_hw_params_t* params, - snd_pcm_access_t access); - virtual int PcmHwParamsSetFormat(snd_pcm_t* handle, - snd_pcm_hw_params_t* params, - snd_pcm_format_t format); - virtual int PcmHwParamsSetChannels(snd_pcm_t* handle, - snd_pcm_hw_params_t* params, - unsigned int num_channels); - virtual int PcmHwParamsSetRateNear(snd_pcm_t* handle, - snd_pcm_hw_params_t* params, - unsigned int* rate, - int* dir); - virtual int PcmHwParamsSetBufferSizeNear(snd_pcm_t* handle, - snd_pcm_hw_params_t* params, - snd_pcm_uframes_t* val); - virtual int PcmHwParamsSetPeriodSizeNear(snd_pcm_t* handle, - snd_pcm_hw_params_t* params, - snd_pcm_uframes_t* val, - int* dir); - virtual int PcmHwParamsTestFormat(snd_pcm_t* handle, - snd_pcm_hw_params_t* params, - snd_pcm_format_t format); virtual int PcmHwParamsTestRate(snd_pcm_t* handle, snd_pcm_hw_params_t* params, unsigned int rate, int dir); - virtual int PcmHwParams(snd_pcm_t* handle, snd_pcm_hw_params_t* params); - virtual int PcmSwParamsMalloc(snd_pcm_sw_params_t** params); - virtual void PcmSwParamsFree(snd_pcm_sw_params_t* params); - virtual int PcmSwParamsCurrent(snd_pcm_t* handle, - snd_pcm_sw_params_t* params); - virtual int PcmSwParamsSetStartThreshold(snd_pcm_t* handle, - snd_pcm_sw_params_t* params, - snd_pcm_uframes_t val); - virtual int PcmSwParamsSetAvailMin(snd_pcm_t* handle, - snd_pcm_sw_params_t* params, - snd_pcm_uframes_t val); virtual int PcmSwParamsSetTstampMode(snd_pcm_t* handle, snd_pcm_sw_params_t* obj, snd_pcm_tstamp_t val); virtual int PcmSwParamsSetTstampType(snd_pcm_t* handle, snd_pcm_sw_params_t* obj, int val); - virtual int PcmSwParams(snd_pcm_t* handle, snd_pcm_sw_params_t* obj); private: DISALLOW_COPY_AND_ASSIGN(AlsaWrapper);
diff --git a/chromecast/media/cma/backend/android/audio_decoder_android.cc b/chromecast/media/cma/backend/android/audio_decoder_android.cc index 986887c6..ec394250 100644 --- a/chromecast/media/cma/backend/android/audio_decoder_android.cc +++ b/chromecast/media/cma/backend/android/audio_decoder_android.cc
@@ -353,9 +353,9 @@ } } - LOG(INFO) << __func__ << ":" - << " delay=" << delay.delay_microseconds - << " ts=" << delay.timestamp_microseconds; + DVLOG(2) << __func__ << ":" + << " delay=" << delay.delay_microseconds + << " ts=" << delay.timestamp_microseconds; return delay; }
diff --git a/chromecast/media/cma/backend/media_pipeline_backend_manager.cc b/chromecast/media/cma/backend/media_pipeline_backend_manager.cc index 995bfca6..f5266f8 100644 --- a/chromecast/media/cma/backend/media_pipeline_backend_manager.cc +++ b/chromecast/media/cma/backend/media_pipeline_backend_manager.cc
@@ -86,10 +86,11 @@ const media::MediaPipelineDeviceParams& params) { DCHECK(media_task_runner_->BelongsToCurrentThread()); - if (active_backend_wrapper_) { - active_backend_wrapper_->Revoke(); - active_backend_wrapper_ = nullptr; - } + // TODO(guohuideng): Because we now allow multiple CmaBackends to exist, + // we can no longer revoke |active_backend_wrapper_| here unconditionally. + // We will need to only revoke the old |backend_wrapper| if it has active + // video decoder and it has a different |session_id| within its + // MediaPipelineDeviceParams. std::unique_ptr<MediaPipelineBackendWrapper> backend_wrapper = std::make_unique<MediaPipelineBackendWrapper>(params, this);
diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn index 1bf035b..efcaab2 100644 --- a/chromeos/BUILD.gn +++ b/chromeos/BUILD.gn
@@ -428,16 +428,14 @@ # Tast test sources live in the Chromium OS repository. # To diagnose tast failures or disable tests, see go/tast-failures tast_test("chrome_all_tast_tests") { - disabled_tests = [ + tast_disabled_tests = [ # Disabled due to flake. https://crbug.com/909736 "ui.MashLogin", ] - tast_conditional = "!disabled && !\"group:*\" && !informational" + - " && (\"dep:chrome\" || \"dep:chrome_login\")" - foreach(test, disabled_tests) { - tast_conditional += " && !\"name:${test}\"" - } - tast_conditional = "( " + tast_conditional + " )" + } + tast_test("chrome_kevin_tast_tests") { + # Tests that fail on Kevin devices. + tast_disabled_tests = [ "arc.Boot" ] # crbug.com/916367 } group("cros_chrome_deploy") {
diff --git a/chromeos/components/proximity_auth/BUILD.gn b/chromeos/components/proximity_auth/BUILD.gn index 4c5a7b0..517adba 100644 --- a/chromeos/components/proximity_auth/BUILD.gn +++ b/chromeos/components/proximity_auth/BUILD.gn
@@ -55,12 +55,8 @@ "//chromeos/components/multidevice", "//chromeos/components/multidevice/logging", "//chromeos/components/proximity_auth/public/interfaces", - - # TODO(hansberry): Remove this dependency once https://crbug.com/870123 is - # fixed. "//chromeos/services/multidevice_setup/public/cpp", "//chromeos/services/multidevice_setup/public/cpp:prefs", - "//chromeos/services/secure_channel", "//chromeos/services/secure_channel/public/cpp/client", "//chromeos/services/secure_channel/public/mojom", "//components/account_id", @@ -92,7 +88,7 @@ "//chromeos/components/multidevice", "//chromeos/components/multidevice:test_support", "//chromeos/components/multidevice/logging", - "//chromeos/services/device_sync", + "//chromeos/services/device_sync/proto", "//chromeos/services/secure_channel:test_support", "//chromeos/services/secure_channel/public/cpp/client", "//testing/gmock", @@ -123,12 +119,8 @@ "//chromeos/components/multidevice", "//chromeos/components/multidevice:test_support", "//chromeos/components/multidevice/logging", - - # TODO(hansberry): Remove this dependency once https://crbug.com/870123 is - # fixed. "//chromeos/services/multidevice_setup/public/cpp:prefs", "//chromeos/services/multidevice_setup/public/cpp:test_support", - "//chromeos/services/secure_channel", "//chromeos/services/secure_channel:test_support", "//chromeos/services/secure_channel/public/cpp/client:test_support", "//components/prefs:test_support",
diff --git a/chromeos/components/proximity_auth/messenger_impl.cc b/chromeos/components/proximity_auth/messenger_impl.cc index da0b19bc..f98e64be 100644 --- a/chromeos/components/proximity_auth/messenger_impl.cc +++ b/chromeos/components/proximity_auth/messenger_impl.cc
@@ -19,7 +19,6 @@ #include "chromeos/components/multidevice/logging/logging.h" #include "chromeos/components/proximity_auth/messenger_observer.h" #include "chromeos/components/proximity_auth/remote_status_update.h" -#include "chromeos/services/secure_channel/wire_message.h" namespace proximity_auth {
diff --git a/chromeos/components/proximity_auth/messenger_impl_unittest.cc b/chromeos/components/proximity_auth/messenger_impl_unittest.cc index 8933a28e..0fe051e1 100644 --- a/chromeos/components/proximity_auth/messenger_impl_unittest.cc +++ b/chromeos/components/proximity_auth/messenger_impl_unittest.cc
@@ -14,11 +14,7 @@ #include "chromeos/components/multidevice/remote_device_test_util.h" #include "chromeos/components/proximity_auth/messenger_observer.h" #include "chromeos/components/proximity_auth/remote_status_update.h" -#include "chromeos/services/secure_channel/connection.h" -#include "chromeos/services/secure_channel/fake_connection.h" -#include "chromeos/services/secure_channel/fake_secure_context.h" #include "chromeos/services/secure_channel/public/cpp/client/fake_client_channel.h" -#include "chromeos/services/secure_channel/wire_message.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromeos/components/proximity_auth/mock_proximity_auth_client.h b/chromeos/components/proximity_auth/mock_proximity_auth_client.h index 61d5df4..d005a5e 100644 --- a/chromeos/components/proximity_auth/mock_proximity_auth_client.h +++ b/chromeos/components/proximity_auth/mock_proximity_auth_client.h
@@ -10,17 +10,8 @@ #include "base/callback.h" #include "base/macros.h" #include "chromeos/components/proximity_auth/proximity_auth_client.h" -#include "chromeos/services/device_sync/cryptauth_client.h" -#include "chromeos/services/device_sync/cryptauth_device_manager.h" -#include "chromeos/services/device_sync/cryptauth_enrollment_manager.h" #include "testing/gmock/include/gmock/gmock.h" -namespace chromeos { -namespace device_sync { -class CryptAuthClientFactory; -} // namespace device_sync -} // namespace chromeos - namespace proximity_auth { // Mock implementation of ProximityAuthClient. @@ -43,10 +34,6 @@ MOCK_CONST_METHOD0(GetAuthenticatedUsername, std::string(void)); MOCK_METHOD0(GetPrefManager, ProximityAuthPrefManager*(void)); - // Proxy mock methods because implementation requires returning scoped_ptr. - MOCK_METHOD0(CreateCryptAuthClientFactoryPtr, - chromeos::device_sync::CryptAuthClientFactory*(void)); - private: DISALLOW_COPY_AND_ASSIGN(MockProximityAuthClient); };
diff --git a/chromeos/components/proximity_auth/remote_device_life_cycle.h b/chromeos/components/proximity_auth/remote_device_life_cycle.h index 577882f..f4c87a6 100644 --- a/chromeos/components/proximity_auth/remote_device_life_cycle.h +++ b/chromeos/components/proximity_auth/remote_device_life_cycle.h
@@ -9,7 +9,6 @@ #include "base/macros.h" #include "chromeos/components/multidevice/remote_device_ref.h" -#include "chromeos/services/secure_channel/connection.h" namespace chromeos { namespace secure_channel {
diff --git a/chromeos/components/proximity_auth/remote_device_life_cycle_impl.h b/chromeos/components/proximity_auth/remote_device_life_cycle_impl.h index ff27c11..eaf31ce 100644 --- a/chromeos/components/proximity_auth/remote_device_life_cycle_impl.h +++ b/chromeos/components/proximity_auth/remote_device_life_cycle_impl.h
@@ -61,10 +61,6 @@ // |connection_finder_|. void FindConnection(); - // Called when |connection_finder_| finds a connection. - void OnConnectionFound( - std::unique_ptr<chromeos::secure_channel::Connection> connection); - // Creates the messenger which parses status updates. void CreateMessenger();
diff --git a/chromeos/components/proximity_auth/remote_device_life_cycle_impl_unittest.cc b/chromeos/components/proximity_auth/remote_device_life_cycle_impl_unittest.cc index 8f97258..82e94b57 100644 --- a/chromeos/components/proximity_auth/remote_device_life_cycle_impl_unittest.cc +++ b/chromeos/components/proximity_auth/remote_device_life_cycle_impl_unittest.cc
@@ -21,7 +21,6 @@ #include "chromeos/services/secure_channel/public/cpp/client/fake_client_channel.h" #include "chromeos/services/secure_channel/public/cpp/client/fake_connection_attempt.h" #include "chromeos/services/secure_channel/public/cpp/client/fake_secure_channel_client.h" -#include "chromeos/services/secure_channel/wire_message.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromeos/components/proximity_auth/unlock_manager_impl_unittest.cc b/chromeos/components/proximity_auth/unlock_manager_impl_unittest.cc index 5d8d636..b009af6 100644 --- a/chromeos/components/proximity_auth/unlock_manager_impl_unittest.cc +++ b/chromeos/components/proximity_auth/unlock_manager_impl_unittest.cc
@@ -25,10 +25,7 @@ #include "chromeos/components/proximity_auth/remote_status_update.h" #include "chromeos/components/proximity_auth/screenlock_bridge.h" #include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/services/secure_channel/fake_connection.h" -#include "chromeos/services/secure_channel/fake_secure_context.h" #include "chromeos/services/secure_channel/public/cpp/client/fake_client_channel.h" -#include "chromeos/services/secure_channel/secure_context.h" #include "device/bluetooth/bluetooth_adapter_factory.h" #include "device/bluetooth/test/mock_bluetooth_adapter.h" #include "testing/gmock/include/gmock/gmock.h" @@ -70,8 +67,6 @@ MOCK_METHOD0(DispatchUnlockEvent, void()); MOCK_METHOD1(RequestDecryption, void(const std::string& challenge)); MOCK_METHOD0(RequestUnlock, void()); - MOCK_CONST_METHOD0(GetSecureContext, - chromeos::secure_channel::SecureContext*()); MOCK_CONST_METHOD0(GetConnection, chromeos::secure_channel::Connection*()); MOCK_CONST_METHOD0(GetChannel, chromeos::secure_channel::ClientChannel*()); @@ -155,7 +150,6 @@ : remote_device_(chromeos::multidevice::CreateRemoteDeviceRefForTest()), local_device_(chromeos::multidevice::CreateRemoteDeviceRefForTest()), life_cycle_(remote_device_, local_device_), - connection_(remote_device_), fake_client_channel_( std::make_unique<chromeos::secure_channel::FakeClientChannel>()), bluetooth_adapter_(CreateAndRegisterMockBluetoothAdapter()), @@ -184,8 +178,6 @@ ON_CALL(*bluetooth_adapter_, IsPresent()).WillByDefault(Return(true)); ON_CALL(*bluetooth_adapter_, IsPowered()).WillByDefault(Return(true)); ON_CALL(messenger_, SupportsSignIn()).WillByDefault(Return(true)); - ON_CALL(messenger_, GetSecureContext()) - .WillByDefault(Return(&secure_context_)); ON_CALL(messenger_, GetChannel()) .WillByDefault(Return(fake_client_channel_.get())); @@ -220,7 +212,6 @@ chromeos::multidevice::RemoteDeviceRef remote_device_; chromeos::multidevice::RemoteDeviceRef local_device_; FakeRemoteDeviceLifeCycle life_cycle_; - chromeos::secure_channel::FakeConnection connection_; std::unique_ptr<chromeos::secure_channel::FakeClientChannel> fake_client_channel_; @@ -230,7 +221,6 @@ NiceMock<MockProximityAuthClient> proximity_auth_client_; NiceMock<MockMessenger> messenger_; std::unique_ptr<TestUnlockManager> unlock_manager_; - chromeos::secure_channel::FakeSecureContext secure_context_; private: base::test::ScopedFeatureList scoped_feature_list_;
diff --git a/chromeos/components/tether/BUILD.gn b/chromeos/components/tether/BUILD.gn index d54ca62..6c0d8a17 100644 --- a/chromeos/components/tether/BUILD.gn +++ b/chromeos/components/tether/BUILD.gn
@@ -119,17 +119,12 @@ "//chromeos", "//chromeos/components/multidevice/logging", "//chromeos/components/tether/proto", - "//chromeos/services/device_sync", "//chromeos/services/device_sync/public/cpp", "//chromeos/services/multidevice_setup/public/cpp:cpp", "//chromeos/services/multidevice_setup/public/mojom:mojom", "//chromeos/services/secure_channel/public/cpp/client", - "//chromeos/services/secure_channel/public/mojom", - - # TODO(hansberry): Remove //chromeos/services/secure_channel dependency when - # SecureChannelClient migration is complete. - "//chromeos/services/secure_channel", "//chromeos/services/secure_channel/public/cpp/shared", + "//chromeos/services/secure_channel/public/mojom", "//components/pref_registry", "//components/prefs", "//components/session_manager/core", @@ -209,10 +204,6 @@ "//chromeos/components/multidevice:test_support", "//chromeos/components/tether/proto", "//chromeos/services/device_sync/public/cpp:test_support", - - # TODO(hansberry): Remove //chromeos/services/secure_channel dependency when - # SecureChannelClient migration is complete. - "//chromeos/services/secure_channel", "//chromeos/services/secure_channel/public/cpp/client:test_support", "//chromeos/services/secure_channel/public/cpp/shared", "//device/bluetooth", @@ -274,18 +265,12 @@ "//chromeos/components/multidevice", "//chromeos/components/multidevice:test_support", "//chromeos/components/tether/proto", - "//chromeos/services/device_sync", "//chromeos/services/device_sync:test_support", "//chromeos/services/device_sync/public/cpp", "//chromeos/services/device_sync/public/cpp:test_support", - - # TODO(hansberry): Remove //chromeos/services/secure_channel dependency when - # SecureChannelClient migration is complete. - "//chromeos/components/multidevice:test_support", "//chromeos/services/device_sync/public/mojom", "//chromeos/services/multidevice_setup/public/cpp:test_support", "//chromeos/services/multidevice_setup/public/mojom:mojom", - "//chromeos/services/secure_channel", "//chromeos/services/secure_channel:test_support", "//chromeos/services/secure_channel/public/cpp/client:test_support", "//chromeos/services/secure_channel/public/cpp/shared",
diff --git a/chromeos/components/tether/host_scanner_impl.cc b/chromeos/components/tether/host_scanner_impl.cc index 196b3931..c08d986d 100644 --- a/chromeos/components/tether/host_scanner_impl.cc +++ b/chromeos/components/tether/host_scanner_impl.cc
@@ -17,7 +17,6 @@ #include "chromeos/components/tether/master_host_scan_cache.h" #include "chromeos/components/tether/tether_host_fetcher.h" #include "chromeos/network/network_state.h" -#include "chromeos/services/device_sync/remote_device_loader.h" #include "components/session_manager/core/session_manager.h" namespace chromeos {
diff --git a/chromeos/dbus/DEPS b/chromeos/dbus/DEPS index 840af75..178e81e 100644 --- a/chromeos/dbus/DEPS +++ b/chromeos/dbus/DEPS
@@ -2,8 +2,9 @@ include_rules = [ "+base", + # Please do not add any additional chromeos/ dependencies here, see + # https://crbug.com/863439 "+chromeos/chromeos_export.h", - "+chromeos/chromeos_features.h", "+components/account_id/account_id.h", "+components/device_event_log", "+components/policy/proto",
diff --git a/chromeos/dbus/cros_disks_client.cc b/chromeos/dbus/cros_disks_client.cc index ec5996b..aa899cb4 100644 --- a/chromeos/dbus/cros_disks_client.cc +++ b/chromeos/dbus/cros_disks_client.cc
@@ -25,7 +25,6 @@ #include "base/task_runner_util.h" #include "base/time/time.h" #include "base/values.h" -#include "chromeos/chromeos_features.h" #include "chromeos/dbus/fake_cros_disks_client.h" #include "dbus/bus.h" #include "dbus/message.h" @@ -171,8 +170,6 @@ writer.AppendString(source_format); std::vector<std::string> options = ComposeMountOptions(mount_options, mount_label, access_mode, remount); - if (base::FeatureList::IsEnabled(chromeos::features::kFsNosymfollow)) - options.push_back("nosymfollow"); writer.AppendArrayOfStrings(options); proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::BindOnce(&CrosDisksClientImpl::OnMount,
diff --git a/chromeos/dbus/power_policy_controller.cc b/chromeos/dbus/power_policy_controller.cc index 9bdf6ae5..7420d61 100644 --- a/chromeos/dbus/power_policy_controller.cc +++ b/chromeos/dbus/power_policy_controller.cc
@@ -8,12 +8,10 @@ #include <utility> -#include "base/feature_list.h" #include "base/format_macros.h" #include "base/logging.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" -#include "chromeos/chromeos_features.h" #include "chromeos/dbus/power_manager/backlight.pb.h" // Avoid some ugly line-wrapping later. @@ -115,8 +113,7 @@ presentation_screen_dim_delay_factor(1.0), user_activity_screen_dim_delay_factor(1.0), wait_for_initial_user_activity(false), - force_nonzero_brightness_for_user_activity(true), - smart_dim_enabled(true) {} + force_nonzero_brightness_for_user_activity(true) {} // static std::string PowerPolicyController::GetPolicyDebugString( @@ -245,20 +242,10 @@ } } - // Screen-dim deferral in response to user activity predictions can - // interact poorly with delay scaling, resulting in the system staying - // awake for a long time if a prediction is wrong. See - // https://crbug.com/888392. - if (values.smart_dim_enabled && - base::FeatureList::IsEnabled(features::kUserActivityPrediction)) { - prefs_policy_.set_presentation_screen_dim_delay_factor(1.0); - prefs_policy_.set_user_activity_screen_dim_delay_factor(1.0); - } else { - prefs_policy_.set_presentation_screen_dim_delay_factor( - values.presentation_screen_dim_delay_factor); - prefs_policy_.set_user_activity_screen_dim_delay_factor( - values.user_activity_screen_dim_delay_factor); - } + prefs_policy_.set_presentation_screen_dim_delay_factor( + values.presentation_screen_dim_delay_factor); + prefs_policy_.set_user_activity_screen_dim_delay_factor( + values.user_activity_screen_dim_delay_factor); prefs_policy_.set_wait_for_initial_user_activity( values.wait_for_initial_user_activity);
diff --git a/chromeos/dbus/power_policy_controller.h b/chromeos/dbus/power_policy_controller.h index 3d34d1c9..ffe3a2b 100644 --- a/chromeos/dbus/power_policy_controller.h +++ b/chromeos/dbus/power_policy_controller.h
@@ -78,7 +78,6 @@ double user_activity_screen_dim_delay_factor; bool wait_for_initial_user_activity; bool force_nonzero_brightness_for_user_activity; - bool smart_dim_enabled; }; // Returns a string describing |policy|. Useful for tests.
diff --git a/chromeos/dbus/power_policy_controller_unittest.cc b/chromeos/dbus/power_policy_controller_unittest.cc index 40bf9bcb..9727554 100644 --- a/chromeos/dbus/power_policy_controller_unittest.cc +++ b/chromeos/dbus/power_policy_controller_unittest.cc
@@ -8,8 +8,6 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" -#include "base/test/scoped_feature_list.h" -#include "chromeos/chromeos_features.h" #include "chromeos/dbus/fake_power_manager_client.h" #include "chromeos/dbus/power_manager/backlight.pb.h" #include "testing/gtest/include/gtest/gtest.h" @@ -341,42 +339,6 @@ fake_power_client_->policy())); } -TEST_F(PowerPolicyControllerTest, SmartDimEnabledExperimentEnabled) { - const std::map<std::string, std::string> params = { - {"dim_threshold", "0.651"}}; - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeatureWithParameters( - chromeos::features::kUserActivityPrediction, params); - - PowerPolicyController::PrefValues prefs; - policy_controller_->ApplyPrefs(prefs); - const power_manager::PowerManagementPolicy kDefaultPolicy = - fake_power_client_->policy(); - - // First disable smart dim model. - prefs.smart_dim_enabled = false; - prefs.presentation_screen_dim_delay_factor = 3.0; - prefs.user_activity_screen_dim_delay_factor = 2.0; - policy_controller_->ApplyPrefs(prefs); - - power_manager::PowerManagementPolicy expected_policy = kDefaultPolicy; - expected_policy.set_presentation_screen_dim_delay_factor(3.0); - expected_policy.set_user_activity_screen_dim_delay_factor(2.0); - EXPECT_EQ(PowerPolicyController::GetPolicyDebugString(expected_policy), - PowerPolicyController::GetPolicyDebugString( - fake_power_client_->policy())); - - // Then enable smart dim model. - prefs.smart_dim_enabled = true; - policy_controller_->ApplyPrefs(prefs); - - expected_policy.set_presentation_screen_dim_delay_factor(1.0); - expected_policy.set_user_activity_screen_dim_delay_factor(1.0); - EXPECT_EQ(PowerPolicyController::GetPolicyDebugString(expected_policy), - PowerPolicyController::GetPolicyDebugString( - fake_power_client_->policy())); -} - TEST_F(PowerPolicyControllerTest, PerSessionScreenBrightnessOverride) { const double kAcBrightness = 99.0; const double kBatteryBrightness = 77.0;
diff --git a/chromeos/disks/disk_mount_manager.cc b/chromeos/disks/disk_mount_manager.cc index dca9f546..0aeea9d 100644 --- a/chromeos/disks/disk_mount_manager.cc +++ b/chromeos/disks/disk_mount_manager.cc
@@ -21,6 +21,7 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/strings/string_util.h" +#include "chromeos/chromeos_features.h" #include "chromeos/dbus/cros_disks_client.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/disks/disk.h" @@ -94,8 +95,11 @@ return; } } + std::vector<std::string> options = mount_options; + if (base::FeatureList::IsEnabled(chromeos::features::kFsNosymfollow)) + options.push_back("nosymfollow"); cros_disks_client_->Mount( - source_path, source_format, mount_label, mount_options, access_mode, + source_path, source_format, mount_label, options, access_mode, REMOUNT_OPTION_MOUNT_NEW_DEVICE, base::BindOnce(&DiskMountManagerImpl::OnMount, weak_ptr_factory_.GetWeakPtr(), source_path, type));
diff --git a/chromeos/process_proxy/process_proxy_unittest.cc b/chromeos/process_proxy/process_proxy_unittest.cc index 338925a..6a368d1d 100644 --- a/chromeos/process_proxy/process_proxy_unittest.cc +++ b/chromeos/process_proxy/process_proxy_unittest.cc
@@ -206,6 +206,8 @@ } void EndRegistryTest(base::OnceClosure done_closure) { + base::ScopedAllowBaseSyncPrimitivesForTesting allow_sync_primitives; + registry_->CloseProcess(terminal_id_); int unused_exit_code = 0; @@ -213,7 +215,6 @@ base::GetTerminationStatus(terminal_id_, &unused_exit_code); EXPECT_NE(base::TERMINATION_STATUS_STILL_RUNNING, status); if (status == base::TERMINATION_STATUS_STILL_RUNNING) { - base::ScopedAllowBaseSyncPrimitivesForTesting allow_sync_primitives; base::Process process = base::Process::DeprecatedGetProcessFromHandle(terminal_id_); process.Terminate(0, true);
diff --git a/chromeos/services/assistant/BUILD.gn b/chromeos/services/assistant/BUILD.gn index a124cc6..df67cec 100644 --- a/chromeos/services/assistant/BUILD.gn +++ b/chromeos/services/assistant/BUILD.gn
@@ -63,6 +63,8 @@ "chromium_http_connection.h", "default_url_request_context_getter.cc", "default_url_request_context_getter.h", + "media_session/assistant_media_session.cc", + "media_session/assistant_media_session.h", "platform/audio_input_impl.cc", "platform/audio_input_impl.h", "platform/audio_input_provider_impl.cc", @@ -97,6 +99,8 @@ "//libassistant/shared/public", "//libassistant/shared/public:export", "//net", + "//services/media_session/public/cpp", + "//services/media_session/public/mojom", "//services/network/public/cpp", "//services/network/public/mojom", "//ui/base",
diff --git a/chromeos/services/assistant/DEPS b/chromeos/services/assistant/DEPS index 5282276e..061e3f7 100644 --- a/chromeos/services/assistant/DEPS +++ b/chromeos/services/assistant/DEPS
@@ -10,6 +10,7 @@ "+services/audio/public", "+services/device/public", "+services/identity/public", + "+services/media_session/public", "+services/network/public", "+services/service_manager/public", "+ui/accessibility/ax_assistant_structure.h",
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.cc b/chromeos/services/assistant/assistant_manager_service_impl.cc index 23f3ab5..08531d4 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.cc +++ b/chromeos/services/assistant/assistant_manager_service_impl.cc
@@ -26,6 +26,7 @@ #include "chromeos/assistant/internal/proto/google3/assistant/api/client_op/device_args.pb.h" #include "chromeos/dbus/util/version_loader.h" #include "chromeos/services/assistant/constants.h" +#include "chromeos/services/assistant/media_session/assistant_media_session.h" #include "chromeos/services/assistant/public/features.h" #include "chromeos/services/assistant/service.h" #include "chromeos/services/assistant/utils.h" @@ -98,7 +99,8 @@ device::mojom::BatteryMonitorPtr battery_monitor, Service* service, network::NetworkConnectionTracker* network_connection_tracker) - : action_module_(std::make_unique<action::CrosActionModule>( + : media_session_(std::make_unique<AssistantMediaSession>(connector)), + action_module_(std::make_unique<action::CrosActionModule>( this, base::FeatureList::IsEnabled( assistant::features::kAssistantAppSupport))), @@ -111,8 +113,8 @@ weak_factory_(this) { background_thread_.Start(); platform_api_ = std::make_unique<PlatformApiImpl>( - connector, std::move(battery_monitor), background_thread_.task_runner(), - network_connection_tracker); + connector, media_session_.get(), std::move(battery_monitor), + background_thread_.task_runner(), network_connection_tracker); connector->BindInterface(ash::mojom::kServiceName, &ash_message_center_controller_); } @@ -799,6 +801,9 @@ assistant_client::VoicelessOptions options; options.obfuscated_gaia_id = interaction.user_id; + // Set the request to be user initiated so that a new conversation will be + // created to handle the client OPs in the response of this request. + options.is_user_initiated = true; assistant_manager_internal_->SendVoicelessInteraction( interaction_proto, "verify_provider_response", options, [](auto) {});
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.h b/chromeos/services/assistant/assistant_manager_service_impl.h index 932ed8e..5ec1a57 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.h +++ b/chromeos/services/assistant/assistant_manager_service_impl.h
@@ -42,6 +42,7 @@ namespace assistant { class Service; +class AssistantMediaSession; // Enumeration of Assistant query response type, also recorded in histograms. // These values are persisted to logs. Entries should not be renumbered and @@ -237,6 +238,7 @@ void RecordQueryResponseTypeUMA(); State state_ = State::STOPPED; + std::unique_ptr<AssistantMediaSession> media_session_; std::unique_ptr<PlatformApiImpl> platform_api_; std::unique_ptr<action::CrosActionModule> action_module_; ChromiumApiDelegate chromium_api_delegate_;
diff --git a/chromeos/services/assistant/assistant_settings_manager_impl.cc b/chromeos/services/assistant/assistant_settings_manager_impl.cc index 636ee36..2b56348 100644 --- a/chromeos/services/assistant/assistant_settings_manager_impl.cc +++ b/chromeos/services/assistant/assistant_settings_manager_impl.cc
@@ -177,8 +177,13 @@ case SpeakerIdEnrollmentState::LISTEN: speaker_id_enrollment_done_ = false; // Stop the enrollment since we already get the status. - if (!speaker_id_enrollment_client_) + if (!speaker_id_enrollment_client_) { StopSpeakerIdEnrollment(base::DoNothing()); + // If hotword is enabled but there is no voice model found, launch the + // enrollment flow. + if (service_->assistant_state()->hotword_enabled().value()) + service_->assistant_controller()->StartSpeakerIdEnrollmentFlow(); + } break; case SpeakerIdEnrollmentState::DONE: speaker_id_enrollment_done_ = true;
diff --git a/chromeos/services/assistant/manifest.json b/chromeos/services/assistant/manifest.json index 8333ef7..cc94176 100644 --- a/chromeos/services/assistant/manifest.json +++ b/chromeos/services/assistant/manifest.json
@@ -5,10 +5,11 @@ "service_manager:connector": { "requires": { "ash": [ "system_ui" ], - "identity": [ "identity_manager" ], - "device": [ "device:battery_monitor" ], + "assistant_audio_decoder": [ "assistant:audio_decoder" ], "audio": [ "stream_factory" ], - "assistant_audio_decoder": [ "assistant:audio_decoder" ] + "device": [ "device:battery_monitor" ], + "identity": [ "identity_manager" ], + "media_session": [ "app" ] }, "provides": { "assistant": [
diff --git a/chromeos/services/assistant/media_session/assistant_media_session.cc b/chromeos/services/assistant/media_session/assistant_media_session.cc new file mode 100644 index 0000000..4897909 --- /dev/null +++ b/chromeos/services/assistant/media_session/assistant_media_session.cc
@@ -0,0 +1,133 @@ +// 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/assistant/media_session/assistant_media_session.h" + +#include "services/media_session/public/cpp/switches.h" +#include "services/media_session/public/mojom/constants.mojom.h" +#include "services/service_manager/public/cpp/connector.h" + +namespace chromeos { +namespace assistant { + +namespace { + +using media_session::mojom::AudioFocusType; +using media_session::mojom::MediaPlaybackState; +using media_session::mojom::MediaSessionInfo; + +const char kAudioFocusSourceName[] = "assistant"; + +} // namespace + +AssistantMediaSession::AssistantMediaSession( + service_manager::Connector* connector) + : connector_(connector), binding_(this) {} + +AssistantMediaSession::~AssistantMediaSession() { + AbandonAudioFocusIfNeeded(); +} + +void AssistantMediaSession::GetMediaSessionInfo( + GetMediaSessionInfoCallback callback) { + std::move(callback).Run(GetMediaSessionInfoInternal()); +} + +void AssistantMediaSession::GetDebugInfo(GetDebugInfoCallback callback) { + media_session::mojom::MediaSessionDebugInfoPtr info( + media_session::mojom::MediaSessionDebugInfo::New()); + std::move(callback).Run(std::move(info)); +} + +void AssistantMediaSession::RequestAudioFocus(AudioFocusType audio_focus_type) { + if (!media_session::IsAudioFocusEnabled()) + return; + + if (request_client_ptr_.is_bound()) { + // We have an existing request so we should request an updated focus type. + request_client_ptr_->RequestAudioFocus( + GetMediaSessionInfoInternal(), audio_focus_type, + base::BindOnce(&AssistantMediaSession::FinishAudioFocusRequest, + base::Unretained(this), audio_focus_type)); + return; + } + + EnsureServiceConnection(); + + // Create a mojo interface pointer to our media session. + media_session::mojom::MediaSessionPtr media_session; + binding_.Bind(mojo::MakeRequest(&media_session)); + audio_focus_ptr_->RequestAudioFocus( + mojo::MakeRequest(&request_client_ptr_), std::move(media_session), + GetMediaSessionInfoInternal(), audio_focus_type, + base::BindOnce(&AssistantMediaSession::FinishAudioFocusRequest, + base::Unretained(this), audio_focus_type)); +} + +void AssistantMediaSession::AbandonAudioFocusIfNeeded() { + if (!media_session::IsAudioFocusEnabled()) + return; + + if (audio_focus_state_ == State::INACTIVE) + return; + + SetAudioFocusState(State::INACTIVE); + + if (!request_client_ptr_.is_bound()) + return; + + request_client_ptr_->AbandonAudioFocus(); + request_client_ptr_.reset(); + audio_focus_ptr_.reset(); +} + +void AssistantMediaSession::EnsureServiceConnection() { + DCHECK(media_session::IsAudioFocusEnabled()); + + if (audio_focus_ptr_.is_bound() && !audio_focus_ptr_.encountered_error()) + return; + + audio_focus_ptr_.reset(); + connector_->BindInterface(media_session::mojom::kServiceName, + mojo::MakeRequest(&audio_focus_ptr_)); + audio_focus_ptr_->SetSourceName(kAudioFocusSourceName); +} + +void AssistantMediaSession::FinishAudioFocusRequest( + AudioFocusType audio_focus_type) { + DCHECK(request_client_ptr_.is_bound()); + + SetAudioFocusState(State::ACTIVE); +} + +void AssistantMediaSession::SetAudioFocusState(State audio_focus_state) { + if (audio_focus_state == audio_focus_state_) + return; + + audio_focus_state_ = audio_focus_state; + NotifyMediaSessionInfoChanged(); +} + +media_session::mojom::MediaSessionInfoPtr +AssistantMediaSession::GetMediaSessionInfoInternal() { + media_session::mojom::MediaSessionInfoPtr info( + media_session::mojom::MediaSessionInfo::New()); + // TODO(wutao): Set other states when supporting pause/resume. + info->state = IsActive() ? MediaSessionInfo::SessionState::kActive + : MediaSessionInfo::SessionState::kInactive; + return info; +} + +void AssistantMediaSession::NotifyMediaSessionInfoChanged() { + // TODO(wutao): Notify observers. + if (request_client_ptr_.is_bound()) + request_client_ptr_->MediaSessionInfoChanged(GetMediaSessionInfoInternal()); +} + +bool AssistantMediaSession::IsActive() const { + return audio_focus_state_ == State::ACTIVE; +} + +} // namespace assistant +} // namespace chromeos
diff --git a/chromeos/services/assistant/media_session/assistant_media_session.h b/chromeos/services/assistant/media_session/assistant_media_session.h new file mode 100644 index 0000000..d0a0fbf --- /dev/null +++ b/chromeos/services/assistant/media_session/assistant_media_session.h
@@ -0,0 +1,89 @@ +// 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_ASSISTANT_MEDIA_SESSION_ASSISTANT_MEDIA_SESSION_H_ +#define CHROMEOS_SERVICES_ASSISTANT_MEDIA_SESSION_ASSISTANT_MEDIA_SESSION_H_ + +#include "base/macros.h" +#include "base/timer/timer.h" +#include "base/unguessable_token.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "services/media_session/public/mojom/audio_focus.mojom.h" +#include "services/media_session/public/mojom/media_session.mojom.h" + +namespace service_manager { +class Connector; +} // namespace service_manager + +namespace chromeos { +namespace assistant { + +// MediaSession manages the media session and audio focus for Assistant. +// MediaSession allows clients to observe its changes via MediaSessionObserver, +// and allows clients to resume/suspend/stop the managed players. +class AssistantMediaSession : public media_session::mojom::MediaSession { + public: + enum class State { ACTIVE, INACTIVE }; + + explicit AssistantMediaSession(service_manager::Connector* connector); + ~AssistantMediaSession() override; + + // media_session.mojom.MediaSession overrides: + void Suspend(SuspendType suspend_type) override {} + void Resume(SuspendType suspend_type) override {} + void StartDucking() override {} + void StopDucking() override {} + void GetMediaSessionInfo(GetMediaSessionInfoCallback callback) override; + void GetDebugInfo(GetDebugInfoCallback callback) override; + void AddObserver( + media_session::mojom::MediaSessionObserverPtr observer) override {} + void PreviousTrack() override {} + void NextTrack() override {} + void Seek(base::TimeDelta seek_time) override {} + void Stop(SuspendType suspend_type) override {} + + // Requests/abandons audio focus to the AudioFocusManager. + void RequestAudioFocus(media_session::mojom::AudioFocusType audio_focus_type); + void AbandonAudioFocusIfNeeded(); + + private: + // Ensures that |audio_focus_ptr_| is connected. + void EnsureServiceConnection(); + + // Called by AudioFocusManager when an async audio focus request is completed. + void FinishAudioFocusRequest(media_session::mojom::AudioFocusType type); + + // Returns information about |this|. + media_session::mojom::MediaSessionInfoPtr GetMediaSessionInfoInternal(); + + // Sets |audio_focus_state_| and notifies observers about the state change. + void SetAudioFocusState(State audio_focus_state); + + // Notifies mojo observers that the MediaSessionInfo has changed. + void NotifyMediaSessionInfoChanged(); + + // Returns if the session is currently active. + bool IsActive() const; + + service_manager::Connector* connector_; + + // Binding for Mojo pointer to |this| held by AudioFocusManager. + mojo::Binding<media_session::mojom::MediaSession> binding_; + + // Holds a pointer to the MediaSessionService. + media_session::mojom::AudioFocusManagerPtr audio_focus_ptr_; + + // If the media session has acquired audio focus then this will contain a + // pointer to that requests AudioFocusRequestClient. + media_session::mojom::AudioFocusRequestClientPtr request_client_ptr_; + + State audio_focus_state_ = State::INACTIVE; + + DISALLOW_COPY_AND_ASSIGN(AssistantMediaSession); +}; + +} // namespace assistant +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_ASSISTANT_MEDIA_SESSION_ASSISTANT_MEDIA_SESSION_H_
diff --git a/chromeos/services/assistant/platform/audio_output_provider_impl.cc b/chromeos/services/assistant/platform/audio_output_provider_impl.cc index 065f8d14..b59c1da9b 100644 --- a/chromeos/services/assistant/platform/audio_output_provider_impl.cc +++ b/chromeos/services/assistant/platform/audio_output_provider_impl.cc
@@ -9,12 +9,14 @@ #include "ash/public/interfaces/constants.mojom.h" #include "base/bind.h" +#include "chromeos/services/assistant/media_session/assistant_media_session.h" #include "chromeos/services/assistant/platform/audio_stream_handler.h" #include "chromeos/services/assistant/public/mojom/assistant_audio_decoder.mojom.h" #include "chromeos/services/assistant/public/mojom/constants.mojom.h" #include "libassistant/shared/public/platform_audio_buffer.h" #include "media/audio/audio_device_description.h" #include "media/base/limits.h" +#include "services/media_session/public/mojom/media_session.mojom.h" #include "services/service_manager/public/cpp/connector.h" namespace chromeos { @@ -167,8 +169,10 @@ } // namespace -VolumeControlImpl::VolumeControlImpl(service_manager::Connector* connector) - : binding_(this), +VolumeControlImpl::VolumeControlImpl(service_manager::Connector* connector, + AssistantMediaSession* media_session) + : media_session_(media_session), + binding_(this), main_task_runner_(base::SequencedTaskRunnerHandle::Get()), weak_factory_(this) { connector->BindInterface(ash::mojom::kServiceName, &volume_control_ptr_); @@ -180,7 +184,11 @@ VolumeControlImpl::~VolumeControlImpl() = default; void VolumeControlImpl::SetAudioFocus( - assistant_client::OutputStreamType focused_stream) {} + assistant_client::OutputStreamType focused_stream) { + main_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&VolumeControlImpl::SetAudioFocusOnMainThread, + weak_factory_.GetWeakPtr(), focused_stream)); +} float VolumeControlImpl::GetSystemVolume() { return volume_ * 1.0 / 100.0; @@ -220,6 +228,28 @@ mute_ = mute; } +void VolumeControlImpl::SetAudioFocusOnMainThread( + assistant_client::OutputStreamType focused_stream) { + DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); + // TODO(wutao): Fix the libassistant behavior. + // Currently this is called with |STREAM_TTS| and |STREAM_ALARM| when + // requesting focus. When releasing focus it calls with |STREAM_MEDIA|. + // libassistant media code path does not request focus. + switch (focused_stream) { + case assistant_client::OutputStreamType::STREAM_ALARM: + media_session_->RequestAudioFocus( + media_session::mojom::AudioFocusType::kGainTransientMayDuck); + break; + case assistant_client::OutputStreamType::STREAM_TTS: + media_session_->RequestAudioFocus( + media_session::mojom::AudioFocusType::kGainTransient); + break; + case assistant_client::OutputStreamType::STREAM_MEDIA: + media_session_->AbandonAudioFocusIfNeeded(); + break; + } +} + void VolumeControlImpl::SetSystemVolumeOnMainThread(float new_volume, bool user_initiated) { DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); @@ -233,8 +263,9 @@ AudioOutputProviderImpl::AudioOutputProviderImpl( service_manager::Connector* connector, + AssistantMediaSession* media_session, scoped_refptr<base::SequencedTaskRunner> background_task_runner) - : volume_control_impl_(connector), + : volume_control_impl_(connector, media_session), connector_(connector), main_task_runner_(base::SequencedTaskRunnerHandle::Get()), background_task_runner_(background_task_runner) {
diff --git a/chromeos/services/assistant/platform/audio_output_provider_impl.h b/chromeos/services/assistant/platform/audio_output_provider_impl.h index a4ba40f4c..0d966b4 100644 --- a/chromeos/services/assistant/platform/audio_output_provider_impl.h +++ b/chromeos/services/assistant/platform/audio_output_provider_impl.h
@@ -27,10 +27,13 @@ namespace chromeos { namespace assistant { +class AssistantMediaSession; + class VolumeControlImpl : public assistant_client::VolumeControl, public ash::mojom::VolumeObserver { public: - explicit VolumeControlImpl(service_manager::Connector* connector); + explicit VolumeControlImpl(service_manager::Connector* connector, + AssistantMediaSession* media_session); ~VolumeControlImpl() override; // assistant_client::VolumeControl overrides: @@ -48,9 +51,12 @@ void OnMuteStateChanged(bool mute) override; private: + void SetAudioFocusOnMainThread( + assistant_client::OutputStreamType focused_stream); void SetSystemVolumeOnMainThread(float new_volume, bool user_initiated); void SetSystemMutedOnMainThread(bool muted); + AssistantMediaSession* media_session_; ash::mojom::AssistantVolumeControlPtr volume_control_ptr_; mojo::Binding<ash::mojom::VolumeObserver> binding_; scoped_refptr<base::SequencedTaskRunner> main_task_runner_; @@ -67,6 +73,7 @@ public: explicit AudioOutputProviderImpl( service_manager::Connector* connector, + AssistantMediaSession* media_session, scoped_refptr<base::SequencedTaskRunner> background_task_runner); ~AudioOutputProviderImpl() override;
diff --git a/chromeos/services/assistant/platform_api_impl.cc b/chromeos/services/assistant/platform_api_impl.cc index 481a323..d4fae46 100644 --- a/chromeos/services/assistant/platform_api_impl.cc +++ b/chromeos/services/assistant/platform_api_impl.cc
@@ -8,6 +8,7 @@ #include <utility> #include <vector> +#include "chromeos/services/assistant/media_session/assistant_media_session.h" #include "chromeos/services/assistant/utils.h" #include "libassistant/shared/public/assistant_export.h" #include "libassistant/shared/public/platform_api.h" @@ -73,11 +74,12 @@ PlatformApiImpl::PlatformApiImpl( service_manager::Connector* connector, + AssistantMediaSession* media_session, device::mojom::BatteryMonitorPtr battery_monitor, scoped_refptr<base::SingleThreadTaskRunner> background_task_runner, network::NetworkConnectionTracker* network_connection_tracker) : audio_input_provider_(connector), - audio_output_provider_(connector, background_task_runner), + audio_output_provider_(connector, media_session, background_task_runner), network_provider_(network_connection_tracker), 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 dd3fe19..1792d86 100644 --- a/chromeos/services/assistant/platform_api_impl.h +++ b/chromeos/services/assistant/platform_api_impl.h
@@ -27,11 +27,14 @@ namespace chromeos { namespace assistant { +class AssistantMediaSession; + // Platform API required by the voice assistant. class PlatformApiImpl : public assistant_client::PlatformApi { public: PlatformApiImpl( service_manager::Connector* connector, + AssistantMediaSession* media_session, device::mojom::BatteryMonitorPtr battery_monitor, scoped_refptr<base::SingleThreadTaskRunner> background_task_runner, network::NetworkConnectionTracker* network_connection_tracker);
diff --git a/chromeos/services/device_sync/BUILD.gn b/chromeos/services/device_sync/BUILD.gn index def8fa3..eab6038 100644 --- a/chromeos/services/device_sync/BUILD.gn +++ b/chromeos/services/device_sync/BUILD.gn
@@ -80,6 +80,13 @@ "//services/preferences/public/cpp", "//services/service_manager/public/cpp", ] + + visibility = [ + ":*", + "//chrome/browser", + "//chrome/test:test_support_ui", + "//chromeos/services/device_sync/public/cpp:unit_tests", + ] } service_manifest("manifest") {
diff --git a/chromeos/services/device_sync/cryptauth_device_manager_impl.cc b/chromeos/services/device_sync/cryptauth_device_manager_impl.cc index 14a0b48e..c037f6a 100644 --- a/chromeos/services/device_sync/cryptauth_device_manager_impl.cc +++ b/chromeos/services/device_sync/cryptauth_device_manager_impl.cc
@@ -137,8 +137,7 @@ for (const auto& supported_software_feature : supported_software_features) { dictionary->SetInteger( supported_software_feature, - static_cast<int>( - chromeos::multidevice::SoftwareFeatureState::kSupported)); + static_cast<int>(multidevice::SoftwareFeatureState::kSupported)); } for (const auto& enabled_software_feature : enabled_software_features) { @@ -149,9 +148,9 @@ int software_feature_state; if (!dictionary->GetInteger(software_feature_key, &software_feature_state) || - static_cast<chromeos::multidevice::SoftwareFeatureState>( + static_cast<multidevice::SoftwareFeatureState>( software_feature_state) != - chromeos::multidevice::SoftwareFeatureState::kSupported) { + multidevice::SoftwareFeatureState::kSupported) { if (software_feature == cryptauth::SoftwareFeature::EASY_UNLOCK_HOST) { // Allow this known special-case for legacy purposes; fall-through to // logic which marks this device as enabled. @@ -173,8 +172,7 @@ dictionary->SetInteger( software_feature_key, - static_cast<int>( - chromeos::multidevice::SoftwareFeatureState::kEnabled)); + static_cast<int>(multidevice::SoftwareFeatureState::kEnabled)); } // If software features for EASY_UNLOCK_HOST or MAGIC_TETHER_HOST have not @@ -189,8 +187,7 @@ !dictionary->GetInteger(software_feature_key, &software_feature_state)) { dictionary->SetInteger( software_feature_key, - static_cast<int>( - chromeos::multidevice::SoftwareFeatureState::kEnabled)); + static_cast<int>(multidevice::SoftwareFeatureState::kEnabled)); } software_feature_key = SoftwareFeatureEnumToString( cryptauth::SoftwareFeature::MAGIC_TETHER_HOST); @@ -198,8 +195,7 @@ !dictionary->GetInteger(software_feature_key, &software_feature_state)) { dictionary->SetInteger( software_feature_key, - static_cast<int>( - chromeos::multidevice::SoftwareFeatureState::kSupported)); + static_cast<int>(multidevice::SoftwareFeatureState::kSupported)); } return dictionary; @@ -360,12 +356,12 @@ continue; } - switch (static_cast<chromeos::multidevice::SoftwareFeatureState>( + switch (static_cast<multidevice::SoftwareFeatureState>( software_feature_state)) { - case chromeos::multidevice::SoftwareFeatureState::kEnabled: + case multidevice::SoftwareFeatureState::kEnabled: external_device->add_enabled_software_features(software_feature); FALLTHROUGH; - case chromeos::multidevice::SoftwareFeatureState::kSupported: + case multidevice::SoftwareFeatureState::kSupported: external_device->add_supported_software_features(software_feature); break; default:
diff --git a/chromeos/services/device_sync/cryptauth_device_manager_impl_unittest.cc b/chromeos/services/device_sync/cryptauth_device_manager_impl_unittest.cc index 27f05b6..23422ad 100644 --- a/chromeos/services/device_sync/cryptauth_device_manager_impl_unittest.cc +++ b/chromeos/services/device_sync/cryptauth_device_manager_impl_unittest.cc
@@ -326,12 +326,12 @@ cryptauth::SoftwareFeature software_feature = SoftwareFeatureStringToEnum(it.first); - switch (static_cast<chromeos::multidevice::SoftwareFeatureState>( + switch (static_cast<multidevice::SoftwareFeatureState>( software_feature_state)) { - case chromeos::multidevice::SoftwareFeatureState::kEnabled: + case multidevice::SoftwareFeatureState::kEnabled: enabled_software_features.push_back(software_feature); FALLTHROUGH; - case chromeos::multidevice::SoftwareFeatureState::kSupported: + case multidevice::SoftwareFeatureState::kSupported: supported_software_features.push_back(software_feature); break; default:
diff --git a/chromeos/services/device_sync/device_sync_base.cc b/chromeos/services/device_sync/device_sync_base.cc index f6448bc..b64bd114 100644 --- a/chromeos/services/device_sync/device_sync_base.cc +++ b/chromeos/services/device_sync/device_sync_base.cc
@@ -7,56 +7,17 @@ #include "base/bind.h" #include "base/callback.h" #include "chromeos/services/device_sync/device_sync_base.h" -#include "components/gcm_driver/gcm_app_handler.h" -#include "components/gcm_driver/gcm_driver.h" namespace chromeos { namespace device_sync { -namespace { - -const char kDummyAppName[] = "DeviceSyncDummyApp"; - -class DummyGCMAppHandler : public gcm::GCMAppHandler { - public: - explicit DummyGCMAppHandler(base::OnceClosure shutdown_callback) - : shutdown_callback_(std::move(shutdown_callback)) {} - ~DummyGCMAppHandler() override = default; - - // gcm::GCMAppHandler: - void ShutdownHandler() override { std::move(shutdown_callback_).Run(); } - - void OnStoreReset() override {} - void OnMessage(const std::string& app_id, - const gcm::IncomingMessage& message) override {} - void OnMessagesDeleted(const std::string& app_id) override {} - void OnSendError( - const std::string& app_id, - const gcm::GCMClient::SendErrorDetails& send_error_details) override {} - void OnSendAcknowledged(const std::string& app_id, - const std::string& message_id) override {} - - private: - base::OnceClosure shutdown_callback_; -}; - -} // namespace - -DeviceSyncBase::DeviceSyncBase(gcm::GCMDriver* gcm_driver) - : gcm_app_handler_(std::make_unique<DummyGCMAppHandler>( - base::BindOnce(&DeviceSyncBase::Shutdown, base::Unretained(this)))), - gcm_driver_(gcm_driver) { - if (gcm_driver_) - gcm_driver_->AddAppHandler(kDummyAppName, gcm_app_handler_.get()); +DeviceSyncBase::DeviceSyncBase() { bindings_.set_connection_error_handler(base::BindRepeating( &DeviceSyncBase::OnDisconnection, base::Unretained(this))); } -DeviceSyncBase::~DeviceSyncBase() { - if (gcm_driver_) - gcm_driver_->RemoveAppHandler(kDummyAppName); -} +DeviceSyncBase::~DeviceSyncBase() = default; void DeviceSyncBase::AddObserver(mojom::DeviceSyncObserverPtr observer, AddObserverCallback callback) {
diff --git a/chromeos/services/device_sync/device_sync_base.h b/chromeos/services/device_sync/device_sync_base.h index 427bbf69..eae48ee 100644 --- a/chromeos/services/device_sync/device_sync_base.h +++ b/chromeos/services/device_sync/device_sync_base.h
@@ -9,15 +9,9 @@ #include "base/macros.h" #include "chromeos/services/device_sync/public/mojom/device_sync.mojom.h" -#include "components/signin/core/browser/account_info.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/interface_ptr_set.h" -namespace gcm { -class GCMAppHandler; -class GCMDriver; -} // namespace gcm - namespace chromeos { namespace device_sync { @@ -38,7 +32,7 @@ void CloseAllBindings(); protected: - explicit DeviceSyncBase(gcm::GCMDriver* gcm_driver); + DeviceSyncBase(); // Derived types should override this function to remove references to any // dependencies. @@ -53,10 +47,6 @@ mojo::InterfacePtrSet<mojom::DeviceSyncObserver> observers_; mojo::BindingSet<mojom::DeviceSync> bindings_; - std::unique_ptr<gcm::GCMAppHandler> gcm_app_handler_; - - gcm::GCMDriver* gcm_driver_; - DISALLOW_COPY_AND_ASSIGN(DeviceSyncBase); };
diff --git a/chromeos/services/device_sync/device_sync_impl.cc b/chromeos/services/device_sync/device_sync_impl.cc index b06a905..6169bf046 100644 --- a/chromeos/services/device_sync/device_sync_impl.cc +++ b/chromeos/services/device_sync/device_sync_impl.cc
@@ -293,7 +293,7 @@ base::Clock* clock, std::unique_ptr<PrefConnectionDelegate> pref_connection_delegate, std::unique_ptr<base::OneShotTimer> timer) - : DeviceSyncBase(gcm_driver), + : DeviceSyncBase(), identity_manager_(identity_manager), gcm_driver_(gcm_driver), connector_(connector),
diff --git a/chromeos/services/device_sync/device_sync_service.h b/chromeos/services/device_sync/device_sync_service.h index 083eb19..8d834ee 100644 --- a/chromeos/services/device_sync/device_sync_service.h +++ b/chromeos/services/device_sync/device_sync_service.h
@@ -32,9 +32,8 @@ class DeviceSyncBase; class GcmDeviceInfoProvider; -// Service which provides an implementation for -// device_sync::mojom::DeviceSync. This service creates one -// implementation and shares it among all connection requests. +// Service which provides an implementation for DeviceSync. This service creates +// one implementation and shares it among all connection requests. class DeviceSyncService : public service_manager::Service { public: DeviceSyncService(
diff --git a/chromeos/services/device_sync/device_sync_service_unittest.cc b/chromeos/services/device_sync/device_sync_service_unittest.cc index 5d04b55..bf9d8c4 100644 --- a/chromeos/services/device_sync/device_sync_service_unittest.cc +++ b/chromeos/services/device_sync/device_sync_service_unittest.cc
@@ -503,8 +503,7 @@ service_ = std::make_unique<DeviceSyncService>( identity_test_environment_->identity_manager(), fake_gcm_driver_.get(), fake_gcm_device_info_provider_.get(), shared_url_loader_factory, - connector_factory_.RegisterInstance( - chromeos::device_sync::mojom::kServiceName)); + connector_factory_.RegisterInstance(mojom::kServiceName)); } void TearDown() override { DBusThreadManager::Shutdown(); } @@ -1156,7 +1155,7 @@ auto last_response = GetLastSetSoftwareFeatureStateResponseAndReset(); EXPECT_TRUE(last_response); - EXPECT_EQ(device_sync::mojom::NetworkRequestResult::kSuccess, *last_response); + EXPECT_EQ(mojom::NetworkRequestResult::kSuccess, *last_response); histogram_tester().ExpectBucketCount<bool>( "MultiDevice.DeviceSyncService.SetSoftwareFeatureState.Result", false, 0); @@ -1204,8 +1203,7 @@ auto last_response = GetLastSetSoftwareFeatureStateResponseAndReset(); EXPECT_TRUE(last_response); - EXPECT_EQ(device_sync::mojom::NetworkRequestResult:: - kRequestSucceededButUnexpectedResult, + EXPECT_EQ(mojom::NetworkRequestResult::kRequestSucceededButUnexpectedResult, *last_response); histogram_tester().ExpectBucketCount<bool>( @@ -1290,8 +1288,7 @@ base::RunLoop().RunUntilIdle(); auto last_response = GetLastFindEligibleDevicesResponseAndReset(); EXPECT_TRUE(last_response); - EXPECT_EQ(device_sync::mojom::NetworkRequestResult::kSuccess, - last_response->first); + EXPECT_EQ(mojom::NetworkRequestResult::kSuccess, last_response->first); EXPECT_EQ(last_response->second->eligible_devices, multidevice::RemoteDeviceList(test_devices().begin(), test_devices().begin()));
diff --git a/chromeos/services/device_sync/fake_device_sync.cc b/chromeos/services/device_sync/fake_device_sync.cc index ba87c117..cdbf43c 100644 --- a/chromeos/services/device_sync/fake_device_sync.cc +++ b/chromeos/services/device_sync/fake_device_sync.cc
@@ -14,7 +14,7 @@ namespace device_sync { -FakeDeviceSync::FakeDeviceSync() : DeviceSyncBase(nullptr /* gcm_driver */) {} +FakeDeviceSync::FakeDeviceSync() : DeviceSyncBase() {} FakeDeviceSync::~FakeDeviceSync() = default;
diff --git a/chromeos/services/device_sync/fake_device_sync_observer.h b/chromeos/services/device_sync/fake_device_sync_observer.h index d937b18a..23587ad 100644 --- a/chromeos/services/device_sync/fake_device_sync_observer.h +++ b/chromeos/services/device_sync/fake_device_sync_observer.h
@@ -14,7 +14,7 @@ namespace device_sync { // Fake DeviceSyncObserver implementation for tests. -class FakeDeviceSyncObserver : public device_sync::mojom::DeviceSyncObserver { +class FakeDeviceSyncObserver : public mojom::DeviceSyncObserver { public: FakeDeviceSyncObserver(); ~FakeDeviceSyncObserver() override; @@ -24,7 +24,7 @@ size_t num_enrollment_events() { return num_enrollment_events_; } size_t num_sync_events() { return num_sync_events_; } - // device_sync::mojom::DeviceSyncObserver: + // mojom::DeviceSyncObserver: void OnEnrollmentFinished() override; void OnNewDevicesSynced() override;
diff --git a/chromeos/services/device_sync/fake_remote_device_provider.cc b/chromeos/services/device_sync/fake_remote_device_provider.cc index f28f89a..98143f1 100644 --- a/chromeos/services/device_sync/fake_remote_device_provider.cc +++ b/chromeos/services/device_sync/fake_remote_device_provider.cc
@@ -16,7 +16,7 @@ RemoteDeviceProvider::NotifyObserversDeviceListChanged(); } -const chromeos::multidevice::RemoteDeviceList& +const multidevice::RemoteDeviceList& FakeRemoteDeviceProvider::GetSyncedDevices() const { return synced_remote_devices_; }
diff --git a/chromeos/services/device_sync/fake_remote_device_provider.h b/chromeos/services/device_sync/fake_remote_device_provider.h index 9206b0399..ae35de0c 100644 --- a/chromeos/services/device_sync/fake_remote_device_provider.h +++ b/chromeos/services/device_sync/fake_remote_device_provider.h
@@ -18,18 +18,17 @@ ~FakeRemoteDeviceProvider() override; void set_synced_remote_devices( - const chromeos::multidevice::RemoteDeviceList& synced_remote_devices) { + const multidevice::RemoteDeviceList& synced_remote_devices) { synced_remote_devices_ = synced_remote_devices; } void NotifyObserversDeviceListChanged(); // RemoteDeviceProvider: - const chromeos::multidevice::RemoteDeviceList& GetSyncedDevices() - const override; + const multidevice::RemoteDeviceList& GetSyncedDevices() const override; private: - chromeos::multidevice::RemoteDeviceList synced_remote_devices_; + multidevice::RemoteDeviceList synced_remote_devices_; DISALLOW_COPY_AND_ASSIGN(FakeRemoteDeviceProvider); };
diff --git a/chromeos/services/device_sync/fake_software_feature_manager.cc b/chromeos/services/device_sync/fake_software_feature_manager.cc index a2e3cee..743acf8 100644 --- a/chromeos/services/device_sync/fake_software_feature_manager.cc +++ b/chromeos/services/device_sync/fake_software_feature_manager.cc
@@ -11,7 +11,7 @@ FakeSoftwareFeatureManager::SetSoftwareFeatureStateArgs:: SetSoftwareFeatureStateArgs( const std::string& public_key, - chromeos::multidevice::SoftwareFeature software_feature, + multidevice::SoftwareFeature software_feature, bool enabled, const base::Closure& success_callback, const base::Callback<void(NetworkRequestError)>& error_callback, @@ -27,7 +27,7 @@ ~SetSoftwareFeatureStateArgs() = default; FakeSoftwareFeatureManager::FindEligibleDevicesArgs::FindEligibleDevicesArgs( - chromeos::multidevice::SoftwareFeature software_feature, + multidevice::SoftwareFeature software_feature, const base::Callback<void(const std::vector<cryptauth::ExternalDeviceInfo>&, const std::vector<cryptauth::IneligibleDevice>&)>& success_callback, @@ -45,7 +45,7 @@ void FakeSoftwareFeatureManager::SetSoftwareFeatureState( const std::string& public_key, - chromeos::multidevice::SoftwareFeature software_feature, + multidevice::SoftwareFeature software_feature, bool enabled, const base::Closure& success_callback, const base::Callback<void(NetworkRequestError)>& error_callback, @@ -60,7 +60,7 @@ } void FakeSoftwareFeatureManager::FindEligibleDevices( - chromeos::multidevice::SoftwareFeature software_feature, + multidevice::SoftwareFeature software_feature, const base::Callback<void(const std::vector<cryptauth::ExternalDeviceInfo>&, const std::vector<cryptauth::IneligibleDevice>&)>& success_callback,
diff --git a/chromeos/services/device_sync/fake_software_feature_manager.h b/chromeos/services/device_sync/fake_software_feature_manager.h index 4cae305..52c9daa 100644 --- a/chromeos/services/device_sync/fake_software_feature_manager.h +++ b/chromeos/services/device_sync/fake_software_feature_manager.h
@@ -30,7 +30,7 @@ struct SetSoftwareFeatureStateArgs { SetSoftwareFeatureStateArgs( const std::string& public_key, - chromeos::multidevice::SoftwareFeature software_feature, + multidevice::SoftwareFeature software_feature, bool enabled, const base::Closure& success_callback, const base::Callback<void(NetworkRequestError)>& error_callback, @@ -38,7 +38,7 @@ ~SetSoftwareFeatureStateArgs(); std::string public_key; - chromeos::multidevice::SoftwareFeature software_feature; + multidevice::SoftwareFeature software_feature; bool enabled; base::Closure success_callback; base::Callback<void(NetworkRequestError)> error_callback; @@ -50,14 +50,14 @@ struct FindEligibleDevicesArgs { FindEligibleDevicesArgs( - chromeos::multidevice::SoftwareFeature software_feature, + multidevice::SoftwareFeature software_feature, const base::Callback<void( const std::vector<cryptauth::ExternalDeviceInfo>&, const std::vector<cryptauth::IneligibleDevice>&)>& success_callback, const base::Callback<void(NetworkRequestError)>& error_callback); ~FindEligibleDevicesArgs(); - chromeos::multidevice::SoftwareFeature software_feature; + multidevice::SoftwareFeature software_feature; base::Callback<void(const std::vector<cryptauth::ExternalDeviceInfo>&, const std::vector<cryptauth::IneligibleDevice>&)> success_callback; @@ -85,13 +85,13 @@ // SoftwareFeatureManager: void SetSoftwareFeatureState( const std::string& public_key, - chromeos::multidevice::SoftwareFeature software_feature, + multidevice::SoftwareFeature software_feature, bool enabled, const base::Closure& success_callback, const base::Callback<void(NetworkRequestError)>& error_callback, bool is_exclusive = false) override; void FindEligibleDevices( - chromeos::multidevice::SoftwareFeature software_feature, + multidevice::SoftwareFeature software_feature, const base::Callback<void( const std::vector<cryptauth::ExternalDeviceInfo>&, const std::vector<cryptauth::IneligibleDevice>&)>& success_callback,
diff --git a/chromeos/services/device_sync/public/cpp/device_sync_client_impl.h b/chromeos/services/device_sync/public/cpp/device_sync_client_impl.h index 70415595..1eb80badf 100644 --- a/chromeos/services/device_sync/public/cpp/device_sync_client_impl.h +++ b/chromeos/services/device_sync/public/cpp/device_sync_client_impl.h
@@ -38,7 +38,7 @@ // Concrete implementation of DeviceSyncClient. class DeviceSyncClientImpl : public DeviceSyncClient, - public device_sync::mojom::DeviceSyncObserver { + public mojom::DeviceSyncObserver { public: class Factory { public: @@ -72,7 +72,7 @@ FindEligibleDevicesCallback callback) override; void GetDebugInfo(mojom::DeviceSync::GetDebugInfoCallback callback) override; - // device_sync::mojom::DeviceSyncObserver: + // mojom::DeviceSyncObserver: void OnEnrollmentFinished() override; void OnNewDevicesSynced() override;
diff --git a/chromeos/services/device_sync/public/cpp/device_sync_client_impl_unittest.cc b/chromeos/services/device_sync/public/cpp/device_sync_client_impl_unittest.cc index 53fd792e..ff36da2 100644 --- a/chromeos/services/device_sync/public/cpp/device_sync_client_impl_unittest.cc +++ b/chromeos/services/device_sync/public/cpp/device_sync_client_impl_unittest.cc
@@ -144,8 +144,7 @@ void SetUp() override { fake_gcm_driver_ = std::make_unique<gcm::FakeGCMDriver>(); fake_gcm_device_info_provider_ = - std::make_unique<device_sync::FakeGcmDeviceInfoProvider>( - GetTestGcmDeviceInfo()); + std::make_unique<FakeGcmDeviceInfoProvider>(GetTestGcmDeviceInfo()); identity_test_environment_ = std::make_unique<identity::IdentityTestEnvironment>(); @@ -169,8 +168,7 @@ service_ = std::make_unique<DeviceSyncService>( identity_test_environment_->identity_manager(), fake_gcm_driver_.get(), fake_gcm_device_info_provider_.get(), shared_url_loader_factory, - connector_factory_.RegisterInstance( - chromeos::device_sync::mojom::kServiceName)); + connector_factory_.RegisterInstance(mojom::kServiceName)); test_observer_ = std::make_unique<TestDeviceSyncClientObserver>(); @@ -421,8 +419,7 @@ std::unique_ptr<identity::IdentityTestEnvironment> identity_test_environment_; std::unique_ptr<gcm::FakeGCMDriver> fake_gcm_driver_; - std::unique_ptr<device_sync::FakeGcmDeviceInfoProvider> - fake_gcm_device_info_provider_; + std::unique_ptr<FakeGcmDeviceInfoProvider> fake_gcm_device_info_provider_; FakeDeviceSync* fake_device_sync_; std::unique_ptr<FakeDeviceSyncImplFactory> fake_device_sync_impl_factory_; service_manager::TestConnectorFactory connector_factory_;
diff --git a/chromeos/services/device_sync/remote_device_loader.cc b/chromeos/services/device_sync/remote_device_loader.cc index db93f7e..8397532c 100644 --- a/chromeos/services/device_sync/remote_device_loader.cc +++ b/chromeos/services/device_sync/remote_device_loader.cc
@@ -23,11 +23,9 @@ namespace { -std::map<chromeos::multidevice::SoftwareFeature, - chromeos::multidevice::SoftwareFeatureState> +std::map<multidevice::SoftwareFeature, multidevice::SoftwareFeatureState> GetSoftwareFeatureToStateMap(const cryptauth::ExternalDeviceInfo& device) { - std::map<chromeos::multidevice::SoftwareFeature, - chromeos::multidevice::SoftwareFeatureState> + std::map<multidevice::SoftwareFeature, multidevice::SoftwareFeatureState> software_feature_to_state_map; for (int i = 0; i < device.supported_software_features_size(); ++i) { @@ -36,8 +34,8 @@ if (feature == cryptauth::UNKNOWN_FEATURE) continue; - software_feature_to_state_map[chromeos::multidevice::FromCryptAuthFeature( - feature)] = chromeos::multidevice::SoftwareFeatureState::kSupported; + software_feature_to_state_map[multidevice::FromCryptAuthFeature(feature)] = + multidevice::SoftwareFeatureState::kSupported; } for (int i = 0; i < device.enabled_software_features_size(); ++i) { @@ -46,8 +44,8 @@ if (feature == cryptauth::UNKNOWN_FEATURE) continue; - software_feature_to_state_map[chromeos::multidevice::FromCryptAuthFeature( - feature)] = chromeos::multidevice::SoftwareFeatureState::kEnabled; + software_feature_to_state_map[multidevice::FromCryptAuthFeature(feature)] = + multidevice::SoftwareFeatureState::kEnabled; } return software_feature_to_state_map; @@ -138,13 +136,13 @@ DCHECK(iterator != remaining_devices_.end()); remaining_devices_.erase(iterator); - std::vector<chromeos::multidevice::BeaconSeed> multidevice_beacon_seeds; + std::vector<multidevice::BeaconSeed> multidevice_beacon_seeds; for (const auto& cryptauth_beacon_seed : device.beacon_seeds()) { multidevice_beacon_seeds.push_back( - chromeos::multidevice::FromCryptAuthSeed(cryptauth_beacon_seed)); + multidevice::FromCryptAuthSeed(cryptauth_beacon_seed)); } - chromeos::multidevice::RemoteDevice remote_device( + multidevice::RemoteDevice remote_device( user_id_, device.friendly_device_name(), device.public_key(), psk, device.last_update_time_millis(), GetSoftwareFeatureToStateMap(device), multidevice_beacon_seeds);
diff --git a/chromeos/services/device_sync/remote_device_loader.h b/chromeos/services/device_sync/remote_device_loader.h index 6e09ea8..118d90b7 100644 --- a/chromeos/services/device_sync/remote_device_loader.h +++ b/chromeos/services/device_sync/remote_device_loader.h
@@ -22,10 +22,9 @@ namespace device_sync { -// Loads a collection of chromeos::multidevice::RemoteDevice objects from the -// given cryptauth::ExternalDeviceInfo protos that were synced from CryptAuth. -// We need to derive the PSK, which is a symmetric key used to authenticate each -// remote device. +// Loads a collection of RemoteDevice objects from the given ExternalDeviceInfo +// protos that were synced from CryptAuth. We need to derive the PSK, which is a +// symmetric key used to authenticate each remote device. class RemoteDeviceLoader { public: class Factory { @@ -52,8 +51,8 @@ }; // Creates the instance: - // |device_info_list|: The cryptauth::ExternalDeviceInfo objects to convert to - // chromeos::multidevice::RemoteDevice. + // |device_info_list|: The ExternalDeviceInfo objects to convert to + // RemoteDevice. // |user_private_key|: The private key of the user's local device. Used to // derive the PSK. // |secure_message_delegate|: Used to derive each persistent symmetric key. @@ -66,9 +65,8 @@ virtual ~RemoteDeviceLoader(); - // Loads the chromeos::multidevice::RemoteDevice objects. |callback| will be - // invoked upon completion. - typedef base::Callback<void(const chromeos::multidevice::RemoteDeviceList&)> + // Loads the RemoteDevice objects. |callback| will be invoked upon completion. + typedef base::Callback<void(const multidevice::RemoteDeviceList&)> RemoteDeviceCallback; virtual void Load(const RemoteDeviceCallback& callback); @@ -90,11 +88,11 @@ // Performs the PSK key derivation. std::unique_ptr<multidevice::SecureMessageDelegate> secure_message_delegate_; - // Invoked when the chromeos::multidevice::RemoteDevices are loaded. + // Invoked when the RemoteDevices are loaded. RemoteDeviceCallback callback_; - // The collection of chromeos::multidevice::RemoteDevices to return. - chromeos::multidevice::RemoteDeviceList remote_devices_; + // The collection of RemoteDevices to return. + multidevice::RemoteDeviceList remote_devices_; base::WeakPtrFactory<RemoteDeviceLoader> weak_ptr_factory_;
diff --git a/chromeos/services/device_sync/remote_device_loader_unittest.cc b/chromeos/services/device_sync/remote_device_loader_unittest.cc index 69895f20..23ccb730 100644 --- a/chromeos/services/device_sync/remote_device_loader_unittest.cc +++ b/chromeos/services/device_sync/remote_device_loader_unittest.cc
@@ -22,7 +22,7 @@ namespace { -// Prefixes for chromeos::multidevice::RemoteDevice fields. +// Prefixes for RemoteDevice fields. const char kDeviceNamePrefix[] = "device"; const char kPublicKeyPrefix[] = "pk"; @@ -63,7 +63,7 @@ ~DeviceSyncRemoteDeviceLoaderTest() {} void OnRemoteDevicesLoaded( - const chromeos::multidevice::RemoteDeviceList& remote_devices) { + const multidevice::RemoteDeviceList& remote_devices) { remote_devices_ = remote_devices; LoadCompleted(); } @@ -71,16 +71,16 @@ MOCK_METHOD0(LoadCompleted, void()); protected: - // Handles deriving the PSK. Ownership will be passed to the - // chromeos::multidevice::RemoteDeviceLoader under test. + // Handles deriving the PSK. Ownership will be passed to the\ + // RemoteDeviceLoader under test. std::unique_ptr<multidevice::FakeSecureMessageDelegate> secure_message_delegate_; // The private key of the user local device. std::string user_private_key_; - // Stores the result of the chromeos::multidevice::RemoteDeviceLoader. - chromeos::multidevice::RemoteDeviceList remote_devices_; + // Stores the result of the RemoteDeviceLoader. + multidevice::RemoteDeviceList remote_devices_; DISALLOW_COPY_AND_ASSIGN(DeviceSyncRemoteDeviceLoaderTest); }; @@ -116,8 +116,7 @@ ASSERT_EQ(1u, remote_devices_[0].beacon_seeds.size()); const cryptauth::BeaconSeed& beacon_seed = - chromeos::multidevice::ToCryptAuthSeed( - remote_devices_[0].beacon_seeds[0]); + multidevice::ToCryptAuthSeed(remote_devices_[0].beacon_seeds[0]); EXPECT_EQ(kBeaconSeedData, beacon_seed.data()); EXPECT_EQ(kBeaconSeedStartTimeMs, beacon_seed.start_time_millis()); EXPECT_EQ(kBeaconSeedEndTimeMs, beacon_seed.end_time_millis()); @@ -175,17 +174,15 @@ EXPECT_EQ(1u, remote_devices_.size()); - EXPECT_EQ( - chromeos::multidevice::SoftwareFeatureState::kSupported, - remote_devices_[0].software_features - [chromeos::multidevice::SoftwareFeature::kBetterTogetherClient]); - EXPECT_EQ(chromeos::multidevice::SoftwareFeatureState::kEnabled, + EXPECT_EQ(multidevice::SoftwareFeatureState::kSupported, remote_devices_[0].software_features - [chromeos::multidevice::SoftwareFeature::kBetterTogetherHost]); - EXPECT_EQ( - chromeos::multidevice::SoftwareFeatureState::kNotSupported, - remote_devices_[0].software_features - [chromeos::multidevice::SoftwareFeature::kInstantTetheringHost]); + [multidevice::SoftwareFeature::kBetterTogetherClient]); + EXPECT_EQ(multidevice::SoftwareFeatureState::kEnabled, + remote_devices_[0].software_features + [multidevice::SoftwareFeature::kBetterTogetherHost]); + EXPECT_EQ(multidevice::SoftwareFeatureState::kNotSupported, + remote_devices_[0].software_features + [multidevice::SoftwareFeature::kInstantTetheringHost]); } } // namespace device_sync
diff --git a/chromeos/services/device_sync/remote_device_provider.h b/chromeos/services/device_sync/remote_device_provider.h index 76ef1b3d..b2b6860 100644 --- a/chromeos/services/device_sync/remote_device_provider.h +++ b/chromeos/services/device_sync/remote_device_provider.h
@@ -12,9 +12,8 @@ namespace device_sync { -// This class generates and caches chromeos::multidevice::RemoteDevice objects -// when associated metadata has been synced, and updates this cache when a new -// sync occurs. +// This class generates and caches RemoteDevice objects when associated metadata +// has been synced, and updates this cache when a new sync occurs. class RemoteDeviceProvider { public: class Observer { @@ -31,10 +30,8 @@ void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); - // Returns a list of all chromeos::multidevice::RemoteDevices that have been - // synced. - virtual const chromeos::multidevice::RemoteDeviceList& GetSyncedDevices() - const = 0; + // Returns a list of all RemoteDevices that have been synced. + virtual const multidevice::RemoteDeviceList& GetSyncedDevices() const = 0; protected: void NotifyObserversDeviceListChanged();
diff --git a/chromeos/services/device_sync/remote_device_provider_impl.cc b/chromeos/services/device_sync/remote_device_provider_impl.cc index 636496b..03a5359 100644 --- a/chromeos/services/device_sync/remote_device_provider_impl.cc +++ b/chromeos/services/device_sync/remote_device_provider_impl.cc
@@ -85,7 +85,7 @@ } void RemoteDeviceProviderImpl::OnRemoteDevicesLoaded( - const chromeos::multidevice::RemoteDeviceList& synced_remote_devices) { + const multidevice::RemoteDeviceList& synced_remote_devices) { synced_remote_devices_ = synced_remote_devices; remote_device_loader_.reset(); @@ -95,7 +95,7 @@ RemoteDeviceProvider::NotifyObserversDeviceListChanged(); } -const chromeos::multidevice::RemoteDeviceList& +const multidevice::RemoteDeviceList& RemoteDeviceProviderImpl::GetSyncedDevices() const { return synced_remote_devices_; }
diff --git a/chromeos/services/device_sync/remote_device_provider_impl.h b/chromeos/services/device_sync/remote_device_provider_impl.h index 42abd13..9a8a7fcd 100644 --- a/chromeos/services/device_sync/remote_device_provider_impl.h +++ b/chromeos/services/device_sync/remote_device_provider_impl.h
@@ -44,10 +44,8 @@ ~RemoteDeviceProviderImpl() override; - // Returns a list of all chromeos::multidevice::RemoteDevices that have been - // synced. - const chromeos::multidevice::RemoteDeviceList& GetSyncedDevices() - const override; + // RemoteDeviceProvider: + const multidevice::RemoteDeviceList& GetSyncedDevices() const override; // CryptAuthDeviceManager::Observer: void OnSyncFinished( @@ -56,20 +54,19 @@ private: void OnRemoteDevicesLoaded( - const chromeos::multidevice::RemoteDeviceList& synced_remote_devices); + const multidevice::RemoteDeviceList& synced_remote_devices); - // To get cryptauth::ExternalDeviceInfo needed to retrieve - // chromeos::multidevice::RemoteDevices. + // To get cryptauth::ExternalDeviceInfo needed to retrieve RemoteDevices. CryptAuthDeviceManager* device_manager_; // The account ID of the current user. const std::string user_id_; - // The private key used to generate chromeos::multidevice::RemoteDevices. + // The private key used to generate RemoteDevices. const std::string user_private_key_; std::unique_ptr<RemoteDeviceLoader> remote_device_loader_; - chromeos::multidevice::RemoteDeviceList synced_remote_devices_; + multidevice::RemoteDeviceList synced_remote_devices_; base::WeakPtrFactory<RemoteDeviceProviderImpl> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(RemoteDeviceProviderImpl);
diff --git a/chromeos/services/device_sync/remote_device_provider_impl_unittest.cc b/chromeos/services/device_sync/remote_device_provider_impl_unittest.cc index bf25ab5..906d76b 100644 --- a/chromeos/services/device_sync/remote_device_provider_impl_unittest.cc +++ b/chromeos/services/device_sync/remote_device_provider_impl_unittest.cc
@@ -51,11 +51,11 @@ std::vector<cryptauth::ExternalDeviceInfo> CreateExternalDeviceInfosForRemoteDevices( - const chromeos::multidevice::RemoteDeviceList remote_devices) { + const multidevice::RemoteDeviceList remote_devices) { std::vector<cryptauth::ExternalDeviceInfo> device_infos; for (const auto& remote_device : remote_devices) { // Add an cryptauth::ExternalDeviceInfo with the same public key as the - // chromeos::multidevice::RemoteDevice. + // multidevice::RemoteDevice. cryptauth::ExternalDeviceInfo info; info.set_public_key(remote_device.public_key); device_infos.push_back(info); @@ -85,8 +85,7 @@ : public RemoteDeviceLoader::Factory { public: TestRemoteDeviceLoaderFactory() - : test_devices_( - chromeos::multidevice::CreateRemoteDeviceListForTest(5)), + : test_devices_(multidevice::CreateRemoteDeviceListForTest(5)), test_device_infos_( CreateExternalDeviceInfosForRemoteDevices(test_devices_)) {} @@ -111,7 +110,7 @@ ASSERT_TRUE(!callback_.is_null()); // Fetch only the devices inserted by tests, since test_devices_ contains // all available devices. - chromeos::multidevice::RemoteDeviceList devices; + multidevice::RemoteDeviceList devices; for (const auto remote_device : test_devices_) { for (const auto& external_device_info : device_info_list) { if (remote_device.public_key == external_device_info.public_key()) @@ -125,7 +124,7 @@ // Fetch is only started if the change result passed to OnSyncFinished() is // CHANGED and sync is SUCCESS. bool HasQueuedCallback() { return !callback_.is_null(); } - const chromeos::multidevice::RemoteDeviceList test_devices_; + const multidevice::RemoteDeviceList test_devices_; const std::vector<cryptauth::ExternalDeviceInfo> test_device_infos_; void QueueCallback(const RemoteDeviceCallback& callback) { @@ -185,7 +184,7 @@ } void VerifySyncedDevicesMatchExpectation(size_t expected_size) { - chromeos::multidevice::RemoteDeviceList synced_devices = + multidevice::RemoteDeviceList synced_devices = remote_device_provider_->GetSyncedDevices(); EXPECT_EQ(expected_size, synced_devices.size()); EXPECT_EQ(expected_size, fake_device_manager_->GetSyncedDevices().size()); @@ -199,7 +198,7 @@ } } - chromeos::multidevice::RemoteDeviceList test_devices() { + multidevice::RemoteDeviceList test_devices() { return test_device_loader_factory_->test_devices_; }
diff --git a/chromeos/services/device_sync/software_feature_manager.h b/chromeos/services/device_sync/software_feature_manager.h index d89e802..ce3aacd4 100644 --- a/chromeos/services/device_sync/software_feature_manager.h +++ b/chromeos/services/device_sync/software_feature_manager.h
@@ -29,7 +29,7 @@ // ignored. virtual void SetSoftwareFeatureState( const std::string& public_key, - chromeos::multidevice::SoftwareFeature software_feature, + multidevice::SoftwareFeature software_feature, bool enabled, const base::Closure& success_callback, const base::Callback<void(NetworkRequestError)>& error_callback, @@ -38,7 +38,7 @@ // Finds eligible devices associated with the logged-in account which support // |software_feature|. virtual void FindEligibleDevices( - chromeos::multidevice::SoftwareFeature software_feature, + multidevice::SoftwareFeature software_feature, const base::Callback<void( const std::vector<cryptauth::ExternalDeviceInfo>&, const std::vector<cryptauth::IneligibleDevice>&)>& success_callback,
diff --git a/chromeos/services/device_sync/software_feature_manager_impl.cc b/chromeos/services/device_sync/software_feature_manager_impl.cc index 50028c9..8fe8d1b 100644 --- a/chromeos/services/device_sync/software_feature_manager_impl.cc +++ b/chromeos/services/device_sync/software_feature_manager_impl.cc
@@ -74,7 +74,7 @@ void SoftwareFeatureManagerImpl::SetSoftwareFeatureState( const std::string& public_key, - chromeos::multidevice::SoftwareFeature software_feature, + multidevice::SoftwareFeature software_feature, bool enabled, const base::Closure& success_callback, const base::Callback<void(NetworkRequestError)>& error_callback, @@ -83,15 +83,15 @@ // instead of "SetSoftwareFeature" in its name. auto request = std::make_unique<cryptauth::ToggleEasyUnlockRequest>(); request->set_feature(SoftwareFeatureEnumToString( - chromeos::multidevice::ToCryptAuthFeature(software_feature))); + multidevice::ToCryptAuthFeature(software_feature))); request->set_enable(enabled); request->set_is_exclusive(enabled && is_exclusive); // Special case for EasyUnlock: if EasyUnlock is being disabled, set the // apply_to_all property to true, and do not set the public_key field. bool turn_off_easy_unlock_special_case = - !enabled && software_feature == - chromeos::multidevice::SoftwareFeature::kSmartLockHost; + !enabled && + software_feature == multidevice::SoftwareFeature::kSmartLockHost; request->set_apply_to_all(turn_off_easy_unlock_special_case); if (!turn_off_easy_unlock_special_case) request->set_public_key(public_key); @@ -102,7 +102,7 @@ } void SoftwareFeatureManagerImpl::FindEligibleDevices( - chromeos::multidevice::SoftwareFeature software_feature, + multidevice::SoftwareFeature software_feature, const base::Callback<void(const std::vector<cryptauth::ExternalDeviceInfo>&, const std::vector<cryptauth::IneligibleDevice>&)>& success_callback, @@ -112,13 +112,13 @@ auto request = std::make_unique<cryptauth::FindEligibleUnlockDevicesRequest>(); request->set_feature(SoftwareFeatureEnumToString( - chromeos::multidevice::ToCryptAuthFeature(software_feature))); + multidevice::ToCryptAuthFeature(software_feature))); // For historical reasons, the Bluetooth address is abused to mark a which // feature should receive a GCM callback. Read more at // https://crbug.com/883915. request->set_callback_bluetooth_address(SoftwareFeatureEnumToStringAllCaps( - chromeos::multidevice::ToCryptAuthFeature(software_feature))); + multidevice::ToCryptAuthFeature(software_feature))); pending_requests_.emplace(std::make_unique<Request>( std::move(request), success_callback, error_callback));
diff --git a/chromeos/services/device_sync/software_feature_manager_impl.h b/chromeos/services/device_sync/software_feature_manager_impl.h index 99f2e8e5..4ad0098f 100644 --- a/chromeos/services/device_sync/software_feature_manager_impl.h +++ b/chromeos/services/device_sync/software_feature_manager_impl.h
@@ -43,13 +43,13 @@ // SoftwareFeatureManager: void SetSoftwareFeatureState( const std::string& public_key, - chromeos::multidevice::SoftwareFeature software_feature, + multidevice::SoftwareFeature software_feature, bool enabled, const base::Closure& success_callback, const base::Callback<void(NetworkRequestError)>& error_callback, bool is_exclusive = false) override; void FindEligibleDevices( - chromeos::multidevice::SoftwareFeature software_feature, + multidevice::SoftwareFeature software_feature, const base::Callback<void( const std::vector<cryptauth::ExternalDeviceInfo>&, const std::vector<cryptauth::IneligibleDevice>&)>& success_callback,
diff --git a/chromeos/services/device_sync/software_feature_manager_impl_unittest.cc b/chromeos/services/device_sync/software_feature_manager_impl_unittest.cc index 475b5addb..30ce852 100644 --- a/chromeos/services/device_sync/software_feature_manager_impl_unittest.cc +++ b/chromeos/services/device_sync/software_feature_manager_impl_unittest.cc
@@ -38,11 +38,11 @@ std::vector<cryptauth::ExternalDeviceInfo> CreateExternalDeviceInfosForRemoteDevices( - const chromeos::multidevice::RemoteDeviceRefList remote_devices) { + const multidevice::RemoteDeviceRefList remote_devices) { std::vector<cryptauth::ExternalDeviceInfo> device_infos; for (const auto& remote_device : remote_devices) { // Add an cryptauth::ExternalDeviceInfo with the same public key as the - // chromeos::multidevice::RemoteDevice. + // multidevice::RemoteDevice. cryptauth::ExternalDeviceInfo info; info.set_public_key(remote_device.public_key()); device_infos.push_back(info); @@ -59,7 +59,7 @@ DeviceSyncSoftwareFeatureManagerImplTest() : all_test_external_device_infos_( CreateExternalDeviceInfosForRemoteDevices( - chromeos::multidevice::CreateRemoteDeviceRefListForTest(5))), + multidevice::CreateRemoteDeviceRefListForTest(5))), test_eligible_external_devices_infos_( {all_test_external_device_infos_[0], all_test_external_device_infos_[1], @@ -158,7 +158,7 @@ result_ineligible_devices_.clear(); } - void SetSoftwareFeatureState(chromeos::multidevice::SoftwareFeature feature, + void SetSoftwareFeatureState(multidevice::SoftwareFeature feature, const cryptauth::ExternalDeviceInfo& device_info, bool enabled, bool is_exclusive = false) { @@ -172,7 +172,7 @@ is_exclusive); } - void FindEligibleDevices(chromeos::multidevice::SoftwareFeature feature) { + void FindEligibleDevices(multidevice::SoftwareFeature feature) { software_feature_manager_->FindEligibleDevices( feature, base::Bind( @@ -270,16 +270,14 @@ TEST_F(DeviceSyncSoftwareFeatureManagerImplTest, TestOrderUponMultipleRequests) { - SetSoftwareFeatureState( - chromeos::multidevice::SoftwareFeature::kBetterTogetherHost, - test_eligible_external_devices_infos_[0], true /* enable */); - FindEligibleDevices( - chromeos::multidevice::SoftwareFeature::kBetterTogetherHost); - SetSoftwareFeatureState( - chromeos::multidevice::SoftwareFeature::kBetterTogetherClient, - test_eligible_external_devices_infos_[1], false /* enable */); - FindEligibleDevices( - chromeos::multidevice::SoftwareFeature::kBetterTogetherClient); + SetSoftwareFeatureState(multidevice::SoftwareFeature::kBetterTogetherHost, + test_eligible_external_devices_infos_[0], + true /* enable */); + FindEligibleDevices(multidevice::SoftwareFeature::kBetterTogetherHost); + SetSoftwareFeatureState(multidevice::SoftwareFeature::kBetterTogetherClient, + test_eligible_external_devices_infos_[1], + false /* enable */); + FindEligibleDevices(multidevice::SoftwareFeature::kBetterTogetherClient); EXPECT_EQ(SoftwareFeatureEnumToString( cryptauth::SoftwareFeature::BETTER_TOGETHER_HOST), @@ -318,15 +316,15 @@ TEST_F(DeviceSyncSoftwareFeatureManagerImplTest, TestMultipleSetUnlocksRequests) { - SetSoftwareFeatureState( - chromeos::multidevice::SoftwareFeature::kBetterTogetherHost, - test_eligible_external_devices_infos_[0], true /* enable */); - SetSoftwareFeatureState( - chromeos::multidevice::SoftwareFeature::kBetterTogetherClient, - test_eligible_external_devices_infos_[1], false /* enable */); - SetSoftwareFeatureState( - chromeos::multidevice::SoftwareFeature::kBetterTogetherHost, - test_eligible_external_devices_infos_[2], true /* enable */); + SetSoftwareFeatureState(multidevice::SoftwareFeature::kBetterTogetherHost, + test_eligible_external_devices_infos_[0], + true /* enable */); + SetSoftwareFeatureState(multidevice::SoftwareFeature::kBetterTogetherClient, + test_eligible_external_devices_infos_[1], + false /* enable */); + SetSoftwareFeatureState(multidevice::SoftwareFeature::kBetterTogetherHost, + test_eligible_external_devices_infos_[2], + true /* enable */); EXPECT_EQ(SoftwareFeatureEnumToString( cryptauth::SoftwareFeature::BETTER_TOGETHER_HOST), @@ -355,12 +353,9 @@ TEST_F(DeviceSyncSoftwareFeatureManagerImplTest, TestMultipleFindEligibleForUnlockDevicesRequests) { - FindEligibleDevices( - chromeos::multidevice::SoftwareFeature::kBetterTogetherHost); - FindEligibleDevices( - chromeos::multidevice::SoftwareFeature::kBetterTogetherClient); - FindEligibleDevices( - chromeos::multidevice::SoftwareFeature::kBetterTogetherHost); + FindEligibleDevices(multidevice::SoftwareFeature::kBetterTogetherHost); + FindEligibleDevices(multidevice::SoftwareFeature::kBetterTogetherClient); + FindEligibleDevices(multidevice::SoftwareFeature::kBetterTogetherHost); EXPECT_EQ(SoftwareFeatureEnumToString( cryptauth::SoftwareFeature::BETTER_TOGETHER_HOST), @@ -390,11 +385,10 @@ } TEST_F(DeviceSyncSoftwareFeatureManagerImplTest, TestOrderViaMultipleErrors) { - SetSoftwareFeatureState( - chromeos::multidevice::SoftwareFeature::kBetterTogetherHost, - test_eligible_external_devices_infos_[0], true /* enable */); - FindEligibleDevices( - chromeos::multidevice::SoftwareFeature::kBetterTogetherHost); + SetSoftwareFeatureState(multidevice::SoftwareFeature::kBetterTogetherHost, + test_eligible_external_devices_infos_[0], + true /* enable */); + FindEligibleDevices(multidevice::SoftwareFeature::kBetterTogetherHost); EXPECT_EQ(SoftwareFeatureEnumToString( cryptauth::SoftwareFeature::BETTER_TOGETHER_HOST), @@ -412,10 +406,9 @@ } TEST_F(DeviceSyncSoftwareFeatureManagerImplTest, TestIsExclusive) { - SetSoftwareFeatureState( - chromeos::multidevice::SoftwareFeature::kBetterTogetherHost, - test_eligible_external_devices_infos_[0], true /* enable */, - true /* is_exclusive */); + SetSoftwareFeatureState(multidevice::SoftwareFeature::kBetterTogetherHost, + test_eligible_external_devices_infos_[0], + true /* enable */, true /* is_exclusive */); EXPECT_EQ(SoftwareFeatureEnumToString( cryptauth::SoftwareFeature::BETTER_TOGETHER_HOST), @@ -427,9 +420,9 @@ } TEST_F(DeviceSyncSoftwareFeatureManagerImplTest, TestEasyUnlockSpecialCase) { - SetSoftwareFeatureState( - chromeos::multidevice::SoftwareFeature::kSmartLockHost, - test_eligible_external_devices_infos_[0], false /* enable */); + SetSoftwareFeatureState(multidevice::SoftwareFeature::kSmartLockHost, + test_eligible_external_devices_infos_[0], + false /* enable */); EXPECT_EQ( SoftwareFeatureEnumToString(cryptauth::SoftwareFeature::EASY_UNLOCK_HOST),
diff --git a/chromeos/services/multidevice_setup/BUILD.gn b/chromeos/services/multidevice_setup/BUILD.gn index 1ec9184..326660f 100644 --- a/chromeos/services/multidevice_setup/BUILD.gn +++ b/chromeos/services/multidevice_setup/BUILD.gn
@@ -74,6 +74,13 @@ "//components/prefs:prefs", "//services/service_manager/public/cpp", ] + + visibility = [ + ":*", + "//chrome/browser", + "//chromeos/services/multidevice_setup/public/cpp:test_support", + "//chromeos/services/multidevice_setup/public/cpp:unit_tests", + ] } service_manifest("manifest") {
diff --git a/chromeos/services/multidevice_setup/device_reenroller.cc b/chromeos/services/multidevice_setup/device_reenroller.cc index 0056413..b134359d 100644 --- a/chromeos/services/multidevice_setup/device_reenroller.cc +++ b/chromeos/services/multidevice_setup/device_reenroller.cc
@@ -153,7 +153,7 @@ continue; if (local_device_metadata.GetSoftwareFeatureState( - chromeos::multidevice::FromCryptAuthFeature(feature)) != + multidevice::FromCryptAuthFeature(feature)) != multidevice::SoftwareFeatureState::kNotSupported) { sorted_and_deduped_set.insert(feature); }
diff --git a/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.cc b/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.cc index 57ea0fe..ef80b0f9 100644 --- a/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.cc +++ b/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.cc
@@ -63,8 +63,7 @@ } void FakeMultiDeviceSetup::BindHandle(mojo::ScopedMessagePipeHandle handle) { - BindRequest(chromeos::multidevice_setup::mojom::MultiDeviceSetupRequest( - std::move(handle))); + BindRequest(mojom::MultiDeviceSetupRequest(std::move(handle))); } void FakeMultiDeviceSetup::FlushForTesting() {
diff --git a/chromeos/services/secure_channel/BUILD.gn b/chromeos/services/secure_channel/BUILD.gn index b4f7a68..7c66b2b 100644 --- a/chromeos/services/secure_channel/BUILD.gn +++ b/chromeos/services/secure_channel/BUILD.gn
@@ -166,6 +166,12 @@ "//services/service_manager/public/cpp", "//services/service_manager/public/mojom", ] + + visibility = [ + ":*", + "//chrome/browser", + "//chromeos/services/secure_channel/public/cpp/client:unit_tests", + ] } service_manifest("manifest") {
diff --git a/chromeos/services/secure_channel/background_eid_generator.cc b/chromeos/services/secure_channel/background_eid_generator.cc index dacce23..53dfa72 100644 --- a/chromeos/services/secure_channel/background_eid_generator.cc +++ b/chromeos/services/secure_channel/background_eid_generator.cc
@@ -97,7 +97,7 @@ std::string BackgroundEidGenerator::IdentifyRemoteDeviceByAdvertisement( const std::string& advertisement_service_data, - const chromeos::multidevice::RemoteDeviceRefList& remote_devices) const { + const multidevice::RemoteDeviceRefList& remote_devices) const { // Resize the service data to analyze only the first |kNumBytesInEidValue| // bytes. If there are any bytes after those first |kNumBytesInEidValue| // bytes, they are flags, so they are not needed to identify the device which @@ -108,9 +108,8 @@ const auto remote_device_it = std::find_if( remote_devices.begin(), remote_devices.end(), [this, &service_data_without_flags](const auto& remote_device) { - std::vector<DataWithTimestamp> eids = - GenerateNearestEids(chromeos::multidevice::ToCryptAuthSeedList( - remote_device.beacon_seeds())); + std::vector<DataWithTimestamp> eids = GenerateNearestEids( + multidevice::ToCryptAuthSeedList(remote_device.beacon_seeds())); const auto eid_it = std::find_if( eids.begin(), eids.end(), [&service_data_without_flags](auto eid) { return eid.data == service_data_without_flags;
diff --git a/chromeos/services/secure_channel/background_eid_generator.h b/chromeos/services/secure_channel/background_eid_generator.h index 80ce6c99..559a3276 100644 --- a/chromeos/services/secure_channel/background_eid_generator.h +++ b/chromeos/services/secure_channel/background_eid_generator.h
@@ -54,7 +54,7 @@ // device can be identified, returns an empty string. virtual std::string IdentifyRemoteDeviceByAdvertisement( const std::string& advertisement_service_data, - const chromeos::multidevice::RemoteDeviceRefList& remote_devices) const; + const multidevice::RemoteDeviceRefList& remote_devices) const; private: friend class SecureChannelBackgroundEidGeneratorTest;
diff --git a/chromeos/services/secure_channel/background_eid_generator_unittest.cc b/chromeos/services/secure_channel/background_eid_generator_unittest.cc index 682a6a8..8aace16 100644 --- a/chromeos/services/secure_channel/background_eid_generator_unittest.cc +++ b/chromeos/services/secure_channel/background_eid_generator_unittest.cc
@@ -99,14 +99,13 @@ kFourthSeed, kStartPeriodMs + 2 * kBeaconSeedDurationMs, kStartPeriodMs + 3 * kBeaconSeedDurationMs)); - chromeos::multidevice::RemoteDeviceRef device_1 = - chromeos::multidevice::RemoteDeviceRefBuilder() + multidevice::RemoteDeviceRef device_1 = + multidevice::RemoteDeviceRefBuilder() .SetPublicKey("publicKey1") - .SetBeaconSeeds( - chromeos::multidevice::FromCryptAuthSeedList(beacon_seeds_)) + .SetBeaconSeeds(multidevice::FromCryptAuthSeedList(beacon_seeds_)) .Build(); - chromeos::multidevice::RemoteDeviceRef device_2 = - chromeos::multidevice::RemoteDeviceRefBuilder() + multidevice::RemoteDeviceRef device_2 = + multidevice::RemoteDeviceRefBuilder() .SetPublicKey("publicKey2") .Build(); test_remote_devices_ = {device_1, device_2}; @@ -128,7 +127,7 @@ std::unique_ptr<BackgroundEidGenerator> eid_generator_; base::SimpleTestClock test_clock_; std::vector<cryptauth::BeaconSeed> beacon_seeds_; - chromeos::multidevice::RemoteDeviceRefList test_remote_devices_; + multidevice::RemoteDeviceRefList test_remote_devices_; }; TEST_F(SecureChannelBackgroundEidGeneratorTest,
diff --git a/chromeos/services/secure_channel/ble_advertisement_generator.cc b/chromeos/services/secure_channel/ble_advertisement_generator.cc index 4ae973b..df5b266 100644 --- a/chromeos/services/secure_channel/ble_advertisement_generator.cc +++ b/chromeos/services/secure_channel/ble_advertisement_generator.cc
@@ -20,7 +20,7 @@ // static std::unique_ptr<DataWithTimestamp> BleAdvertisementGenerator::GenerateBleAdvertisement( - chromeos::multidevice::RemoteDeviceRef remote_device, + multidevice::RemoteDeviceRef remote_device, const std::string& local_device_public_key) { if (!instance_) instance_ = new BleAdvertisementGenerator(); @@ -42,7 +42,7 @@ std::unique_ptr<DataWithTimestamp> BleAdvertisementGenerator::GenerateBleAdvertisementInternal( - chromeos::multidevice::RemoteDeviceRef remote_device, + multidevice::RemoteDeviceRef remote_device, const std::string& local_device_public_key) { if (local_device_public_key.empty()) { PA_LOG(WARNING) << "Local device's public key is empty. Cannot advertise " @@ -59,8 +59,8 @@ std::unique_ptr<DataWithTimestamp> service_data = eid_generator_->GenerateAdvertisement( - local_device_public_key, chromeos::multidevice::ToCryptAuthSeedList( - remote_device.beacon_seeds())); + local_device_public_key, + multidevice::ToCryptAuthSeedList(remote_device.beacon_seeds())); if (!service_data) { PA_LOG(WARNING) << "Error generating advertisement for device with ID " << remote_device.GetTruncatedDeviceIdForLogs() << ". "
diff --git a/chromeos/services/secure_channel/ble_advertisement_generator.h b/chromeos/services/secure_channel/ble_advertisement_generator.h index e4dfb80..f1158e6e 100644 --- a/chromeos/services/secure_channel/ble_advertisement_generator.h +++ b/chromeos/services/secure_channel/ble_advertisement_generator.h
@@ -31,7 +31,7 @@ // generated advertisement should be used immediately since it is based on the // current timestamp. static std::unique_ptr<DataWithTimestamp> GenerateBleAdvertisement( - chromeos::multidevice::RemoteDeviceRef remote_device, + multidevice::RemoteDeviceRef remote_device, const std::string& local_device_public_key); virtual ~BleAdvertisementGenerator(); @@ -40,15 +40,15 @@ BleAdvertisementGenerator(); virtual std::unique_ptr<DataWithTimestamp> GenerateBleAdvertisementInternal( - chromeos::multidevice::RemoteDeviceRef remote_device, + multidevice::RemoteDeviceRef remote_device, const std::string& local_device_public_key); private: friend class SecureChannelBleAdvertisementGeneratorTest; friend class SecureChannelBleServiceDataHelperImplTest; - friend class chromeos::tether::BleAdvertiserImplTest; - friend class chromeos::tether::BleServiceDataHelperImplTest; - friend class chromeos::tether::AdHocBleAdvertiserImplTest; + friend class tether::BleAdvertiserImplTest; + friend class tether::BleServiceDataHelperImplTest; + friend class tether::AdHocBleAdvertiserImplTest; static BleAdvertisementGenerator* instance_;
diff --git a/chromeos/services/secure_channel/ble_advertisement_generator_unittest.cc b/chromeos/services/secure_channel/ble_advertisement_generator_unittest.cc index 4ea0680..0f8319e 100644 --- a/chromeos/services/secure_channel/ble_advertisement_generator_unittest.cc +++ b/chromeos/services/secure_channel/ble_advertisement_generator_unittest.cc
@@ -49,8 +49,8 @@ protected: SecureChannelBleAdvertisementGeneratorTest() : test_remote_device_( - chromeos::multidevice::RemoteDeviceRefBuilder() - .SetBeaconSeeds(chromeos::multidevice::FromCryptAuthSeedList( + multidevice::RemoteDeviceRefBuilder() + .SetBeaconSeeds(multidevice::FromCryptAuthSeedList( CreateBeaconSeedsForDevice("remote device id"))) .Build()), fake_advertisement_("advertisement1", 1000L, 2000L) {} @@ -66,13 +66,13 @@ void TearDown() override { generator_.reset(); } std::unique_ptr<DataWithTimestamp> CallGenerateBleAdvertisement( - chromeos::multidevice::RemoteDeviceRef remote_device, + multidevice::RemoteDeviceRef remote_device, const std::string& local_device_public_key) { return generator_->GenerateBleAdvertisementInternal( remote_device, local_device_public_key); } - const chromeos::multidevice::RemoteDeviceRef test_remote_device_; + const multidevice::RemoteDeviceRef test_remote_device_; const DataWithTimestamp fake_advertisement_; MockForegroundEidGenerator* mock_eid_generator_; @@ -90,8 +90,7 @@ TEST_F(SecureChannelBleAdvertisementGeneratorTest, EmptyBeaconSeeds) { EXPECT_FALSE(CallGenerateBleAdvertisement( - chromeos::multidevice::CreateRemoteDeviceRefForTest(), - kLocalDevicePublicKey)); + multidevice::CreateRemoteDeviceRefForTest(), kLocalDevicePublicKey)); } TEST_F(SecureChannelBleAdvertisementGeneratorTest,
diff --git a/chromeos/services/secure_channel/ble_scanner_impl.cc b/chromeos/services/secure_channel/ble_scanner_impl.cc index 5a43a0f..665fb39f 100644 --- a/chromeos/services/secure_channel/ble_scanner_impl.cc +++ b/chromeos/services/secure_channel/ble_scanner_impl.cc
@@ -50,7 +50,7 @@ std::unique_ptr<BleScanner> BleScannerImpl::Factory::BuildInstance( Delegate* delegate, - secure_channel::BleServiceDataHelper* service_data_helper, + BleServiceDataHelper* service_data_helper, BleSynchronizerBase* ble_synchronizer, scoped_refptr<device::BluetoothAdapter> adapter) { return base::WrapUnique(new BleScannerImpl(delegate, service_data_helper, @@ -66,11 +66,10 @@ device::BluetoothUUID(kAdvertisingServiceUuid)); } -BleScannerImpl::BleScannerImpl( - Delegate* delegate, - secure_channel::BleServiceDataHelper* service_data_helper, - BleSynchronizerBase* ble_synchronizer, - scoped_refptr<device::BluetoothAdapter> adapter) +BleScannerImpl::BleScannerImpl(Delegate* delegate, + BleServiceDataHelper* service_data_helper, + BleSynchronizerBase* ble_synchronizer, + scoped_refptr<device::BluetoothAdapter> adapter) : BleScanner(delegate), service_data_helper_(service_data_helper), ble_synchronizer_(ble_synchronizer),
diff --git a/chromeos/services/secure_channel/ble_scanner_impl.h b/chromeos/services/secure_channel/ble_scanner_impl.h index 377a201..3e8d6e5 100644 --- a/chromeos/services/secure_channel/ble_scanner_impl.h +++ b/chromeos/services/secure_channel/ble_scanner_impl.h
@@ -37,7 +37,7 @@ static void SetFactoryForTesting(Factory* test_factory); virtual std::unique_ptr<BleScanner> BuildInstance( Delegate* delegate, - secure_channel::BleServiceDataHelper* service_data_helper, + BleServiceDataHelper* service_data_helper, BleSynchronizerBase* ble_synchronizer, scoped_refptr<device::BluetoothAdapter> adapter); @@ -61,7 +61,7 @@ }; BleScannerImpl(Delegate* delegate, - secure_channel::BleServiceDataHelper* service_data_helper, + BleServiceDataHelper* service_data_helper, BleSynchronizerBase* ble_synchronizer, scoped_refptr<device::BluetoothAdapter> adapter); @@ -96,7 +96,7 @@ void SetServiceDataProviderForTesting( std::unique_ptr<ServiceDataProvider> service_data_provider); - secure_channel::BleServiceDataHelper* service_data_helper_; + BleServiceDataHelper* service_data_helper_; BleSynchronizerBase* ble_synchronizer_; scoped_refptr<device::BluetoothAdapter> adapter_;
diff --git a/chromeos/services/secure_channel/ble_service_data_helper_impl.cc b/chromeos/services/secure_channel/ble_service_data_helper_impl.cc index c47545a..bf57423 100644 --- a/chromeos/services/secure_channel/ble_service_data_helper_impl.cc +++ b/chromeos/services/secure_channel/ble_service_data_helper_impl.cc
@@ -154,7 +154,7 @@ // If the device has not yet been identified, try identifying |service_data| // as a background advertisement. - if (chromeos::switches::IsInstantTetheringBackgroundAdvertisingSupported() && + if (switches::IsInstantTetheringBackgroundAdvertisingSupported() && identified_device_id.empty() && service_data.size() >= kMinNumBytesInServiceData && service_data.size() <= kMaxNumBytesInBackgroundServiceData) { @@ -175,7 +175,7 @@ if (identified_device_id.empty()) return base::nullopt; - return secure_channel::BleServiceDataHelper::DeviceWithBackgroundBool( + return BleServiceDataHelper::DeviceWithBackgroundBool( *remote_device_cache_->GetRemoteDevice(identified_device_id), is_background_advertisement); }
diff --git a/chromeos/services/secure_channel/ble_service_data_helper_impl_unittest.cc b/chromeos/services/secure_channel/ble_service_data_helper_impl_unittest.cc index 3d3cae3..9ecaa8c 100644 --- a/chromeos/services/secure_channel/ble_service_data_helper_impl_unittest.cc +++ b/chromeos/services/secure_channel/ble_service_data_helper_impl_unittest.cc
@@ -162,7 +162,7 @@ multidevice::RemoteDeviceRef test_local_device_1_; multidevice::RemoteDeviceRef test_local_device_2_; multidevice::RemoteDeviceRefList test_remote_devices_; - secure_channel::DeviceIdPairSet device_id_pair_set_; + DeviceIdPairSet device_id_pair_set_; DataWithTimestamp fake_advertisement_; @@ -173,35 +173,31 @@ TEST_F(SecureChannelBleServiceDataHelperImplTest, TestGenerateForegroundAdvertisement_CannotGenerateAdvertisement) { fake_ble_advertisement_generator_->set_advertisement(nullptr); - EXPECT_FALSE( - helper_->GenerateForegroundAdvertisement(secure_channel::DeviceIdPair( - test_remote_devices_[0].GetDeviceId() /* remote_device_id */, - test_local_device_1_.GetDeviceId() /* local_device_id */))); + EXPECT_FALSE(helper_->GenerateForegroundAdvertisement( + DeviceIdPair(test_remote_devices_[0].GetDeviceId() /* remote_device_id */, + test_local_device_1_.GetDeviceId() /* local_device_id */))); } TEST_F(SecureChannelBleServiceDataHelperImplTest, TestGenerateForegroundAdvertisement) { - auto data_with_timestamp = - helper_->GenerateForegroundAdvertisement(secure_channel::DeviceIdPair( - test_remote_devices_[0].GetDeviceId() /* remote_device_id */, - test_local_device_1_.GetDeviceId() /* local_device_id */)); + auto data_with_timestamp = helper_->GenerateForegroundAdvertisement( + DeviceIdPair(test_remote_devices_[0].GetDeviceId() /* remote_device_id */, + test_local_device_1_.GetDeviceId() /* local_device_id */)); EXPECT_EQ(fake_advertisement_, *data_with_timestamp); } TEST_F(SecureChannelBleServiceDataHelperImplTest, TestGenerateForegroundAdvertisement_InvalidLocalDevice) { - EXPECT_FALSE( - helper_->GenerateForegroundAdvertisement(secure_channel::DeviceIdPair( - test_remote_devices_[0].GetDeviceId() /* remote_device_id */, - "invalid local device id" /* local_device_id */))); + EXPECT_FALSE(helper_->GenerateForegroundAdvertisement( + DeviceIdPair(test_remote_devices_[0].GetDeviceId() /* remote_device_id */, + "invalid local device id" /* local_device_id */))); } TEST_F(SecureChannelBleServiceDataHelperImplTest, TestGenerateForegroundAdvertisement_InvalidRemoteDevice) { - EXPECT_FALSE( - helper_->GenerateForegroundAdvertisement(secure_channel::DeviceIdPair( - "invalid remote device id" /* remote_device_id */, - test_local_device_1_.GetDeviceId() /* local_device_id */))); + EXPECT_FALSE(helper_->GenerateForegroundAdvertisement( + DeviceIdPair("invalid remote device id" /* remote_device_id */, + test_local_device_1_.GetDeviceId() /* local_device_id */))); } TEST_F(SecureChannelBleServiceDataHelperImplTest,
diff --git a/chromeos/services/secure_channel/ble_weave_client_connection.cc b/chromeos/services/secure_channel/ble_weave_client_connection.cc index 2bfe6f6..d7472fe 100644 --- a/chromeos/services/secure_channel/ble_weave_client_connection.cc +++ b/chromeos/services/secure_channel/ble_weave_client_connection.cc
@@ -58,7 +58,7 @@ // static std::unique_ptr<Connection> BluetoothLowEnergyWeaveClientConnection::Factory::NewInstance( - chromeos::multidevice::RemoteDeviceRef remote_device, + multidevice::RemoteDeviceRef remote_device, scoped_refptr<device::BluetoothAdapter> adapter, const device::BluetoothUUID remote_service_uuid, device::BluetoothDevice* bluetooth_device, @@ -79,7 +79,7 @@ std::unique_ptr<Connection> BluetoothLowEnergyWeaveClientConnection::Factory::BuildInstance( - chromeos::multidevice::RemoteDeviceRef remote_device, + multidevice::RemoteDeviceRef remote_device, scoped_refptr<device::BluetoothAdapter> adapter, const device::BluetoothUUID remote_service_uuid, device::BluetoothDevice* bluetooth_device, @@ -142,7 +142,7 @@ BluetoothLowEnergyWeaveClientConnection:: BluetoothLowEnergyWeaveClientConnection( - chromeos::multidevice::RemoteDeviceRef device, + multidevice::RemoteDeviceRef device, scoped_refptr<device::BluetoothAdapter> adapter, const device::BluetoothUUID remote_service_uuid, device::BluetoothDevice* bluetooth_device,
diff --git a/chromeos/services/secure_channel/ble_weave_client_connection.h b/chromeos/services/secure_channel/ble_weave_client_connection.h index 4de6941af..32df812 100644 --- a/chromeos/services/secure_channel/ble_weave_client_connection.h +++ b/chromeos/services/secure_channel/ble_weave_client_connection.h
@@ -58,7 +58,7 @@ class Factory { public: static std::unique_ptr<Connection> NewInstance( - chromeos::multidevice::RemoteDeviceRef remote_device, + multidevice::RemoteDeviceRef remote_device, scoped_refptr<device::BluetoothAdapter> adapter, const device::BluetoothUUID remote_service_uuid, device::BluetoothDevice* bluetooth_device, @@ -67,7 +67,7 @@ protected: virtual std::unique_ptr<Connection> BuildInstance( - chromeos::multidevice::RemoteDeviceRef remote_device, + multidevice::RemoteDeviceRef remote_device, scoped_refptr<device::BluetoothAdapter> adapter, const device::BluetoothUUID remote_service_uuid, device::BluetoothDevice* bluetooth_device, @@ -93,7 +93,7 @@ // Constructs the Connection object; a subsequent call to Connect() is // necessary to initiate the BLE connection. BluetoothLowEnergyWeaveClientConnection( - chromeos::multidevice::RemoteDeviceRef remote_device, + multidevice::RemoteDeviceRef remote_device, scoped_refptr<device::BluetoothAdapter> adapter, const device::BluetoothUUID remote_service_uuid, device::BluetoothDevice* bluetooth_device,
diff --git a/chromeos/services/secure_channel/ble_weave_client_connection_unittest.cc b/chromeos/services/secure_channel/ble_weave_client_connection_unittest.cc index 346365a5..262f1877 100644 --- a/chromeos/services/secure_channel/ble_weave_client_connection_unittest.cc +++ b/chromeos/services/secure_channel/ble_weave_client_connection_unittest.cc
@@ -214,7 +214,7 @@ : public BluetoothLowEnergyWeaveClientConnection { public: TestBluetoothLowEnergyWeaveClientConnection( - chromeos::multidevice::RemoteDeviceRef remote_device, + multidevice::RemoteDeviceRef remote_device, scoped_refptr<device::BluetoothAdapter> adapter, const device::BluetoothUUID remote_service_uuid, device::MockBluetoothDevice* mock_bluetooth_device, @@ -328,7 +328,7 @@ : public testing::Test { public: SecureChannelBluetoothLowEnergyWeaveClientConnectionTest() - : remote_device_(chromeos::multidevice::CreateRemoteDeviceRefForTest()), + : remote_device_(multidevice::CreateRemoteDeviceRefForTest()), service_uuid_(device::BluetoothUUID(kServiceUUID)), tx_characteristic_uuid_(device::BluetoothUUID(kTXCharacteristicUUID)), rx_characteristic_uuid_(device::BluetoothUUID(kRXCharacteristicUUID)) {} @@ -346,7 +346,7 @@ mock_bluetooth_device_ = std::make_unique<NiceMock<device::MockBluetoothDevice>>( - adapter_.get(), 0, chromeos::multidevice::kTestRemoteDeviceName, + adapter_.get(), 0, multidevice::kTestRemoteDeviceName, kTestRemoteDeviceBluetoothAddress, false, false); service_ = std::make_unique<NiceMock<device::MockBluetoothGattService>>( mock_bluetooth_device_.get(), kServiceID, service_uuid_, true, false); @@ -646,7 +646,7 @@ } protected: - const chromeos::multidevice::RemoteDeviceRef remote_device_; + const multidevice::RemoteDeviceRef remote_device_; const device::BluetoothUUID service_uuid_; const device::BluetoothUUID tx_characteristic_uuid_; const device::BluetoothUUID rx_characteristic_uuid_;
diff --git a/chromeos/services/secure_channel/connection.cc b/chromeos/services/secure_channel/connection.cc index 10e1a7d4..e64025d 100644 --- a/chromeos/services/secure_channel/connection.cc +++ b/chromeos/services/secure_channel/connection.cc
@@ -17,7 +17,7 @@ namespace secure_channel { -Connection::Connection(chromeos::multidevice::RemoteDeviceRef remote_device) +Connection::Connection(multidevice::RemoteDeviceRef remote_device) : remote_device_(remote_device), status_(Status::DISCONNECTED), is_sending_message_(false) {}
diff --git a/chromeos/services/secure_channel/connection.h b/chromeos/services/secure_channel/connection.h index 70cf410..d6bd4d99 100644 --- a/chromeos/services/secure_channel/connection.h +++ b/chromeos/services/secure_channel/connection.h
@@ -33,7 +33,7 @@ }; // Constructs a connection to the given |remote_device|. - explicit Connection(chromeos::multidevice::RemoteDeviceRef remote_device); + explicit Connection(multidevice::RemoteDeviceRef remote_device); virtual ~Connection(); // Returns true iff the connection's status is CONNECTED. @@ -50,9 +50,7 @@ virtual void AddObserver(ConnectionObserver* observer); virtual void RemoveObserver(ConnectionObserver* observer); - chromeos::multidevice::RemoteDeviceRef remote_device() const { - return remote_device_; - } + multidevice::RemoteDeviceRef remote_device() const { return remote_device_; } // Returns the RSSI of the connection; if no derived class overrides this // function, base::nullopt is returned. @@ -107,7 +105,7 @@ private: // The remote device corresponding to this connection. - const chromeos::multidevice::RemoteDeviceRef remote_device_; + const multidevice::RemoteDeviceRef remote_device_; // The current status of the connection. Status status_;
diff --git a/chromeos/services/secure_channel/connection_unittest.cc b/chromeos/services/secure_channel/connection_unittest.cc index 08b586e..961d181 100644 --- a/chromeos/services/secure_channel/connection_unittest.cc +++ b/chromeos/services/secure_channel/connection_unittest.cc
@@ -31,8 +31,7 @@ class MockConnection : public Connection { public: - MockConnection() - : Connection(chromeos::multidevice::CreateRemoteDeviceRefForTest()) {} + MockConnection() : Connection(multidevice::CreateRemoteDeviceRefForTest()) {} ~MockConnection() {} MOCK_METHOD1(SetPaused, void(bool paused));
diff --git a/chromeos/services/secure_channel/device_to_device_authenticator_unittest.cc b/chromeos/services/secure_channel/device_to_device_authenticator_unittest.cc index 66d064d..080fbb3 100644 --- a/chromeos/services/secure_channel/device_to_device_authenticator_unittest.cc +++ b/chromeos/services/secure_channel/device_to_device_authenticator_unittest.cc
@@ -68,7 +68,7 @@ // Connection implementation for testing. class FakeConnection : public Connection { public: - explicit FakeConnection(chromeos::multidevice::RemoteDeviceRef remote_device) + explicit FakeConnection(multidevice::RemoteDeviceRef remote_device) : Connection(remote_device), connection_blocked_(false) {} ~FakeConnection() override {} @@ -141,7 +141,7 @@ class SecureChannelDeviceToDeviceAuthenticatorTest : public testing::Test { public: SecureChannelDeviceToDeviceAuthenticatorTest() - : remote_device_(chromeos::multidevice::CreateRemoteDeviceRefForTest()), + : remote_device_(multidevice::CreateRemoteDeviceRefForTest()), connection_(remote_device_), secure_message_delegate_(new multidevice::FakeSecureMessageDelegate), authenticator_(&connection_, @@ -199,7 +199,7 @@ std::string SimulateResponderAuth(const std::string& hello_message) { std::string remote_device_private_key = secure_message_delegate_->GetPrivateKeyForPublicKey( - chromeos::multidevice::kTestRemoteDevicePublicKey); + multidevice::kTestRemoteDevicePublicKey); std::string responder_auth_message; DeviceToDeviceResponderOperations::CreateResponderAuthMessage( @@ -225,7 +225,7 @@ MOCK_METHOD1(OnAuthenticationResultProxy, void(Authenticator::Result result)); // Contains information about the remote device. - const chromeos::multidevice::RemoteDeviceRef remote_device_; + const multidevice::RemoteDeviceRef remote_device_; // Simulates the connection to the remote device. FakeConnection connection_;
diff --git a/chromeos/services/secure_channel/fake_background_eid_generator.cc b/chromeos/services/secure_channel/fake_background_eid_generator.cc index ca4d442..7a6979b4 100644 --- a/chromeos/services/secure_channel/fake_background_eid_generator.cc +++ b/chromeos/services/secure_channel/fake_background_eid_generator.cc
@@ -20,7 +20,7 @@ std::string FakeBackgroundEidGenerator::IdentifyRemoteDeviceByAdvertisement( const std::string& advertisement_service_data, - const chromeos::multidevice::RemoteDeviceRefList& remote_devices) const { + const multidevice::RemoteDeviceRefList& remote_devices) const { // Increment num_identify_calls_. Since this overrides a const method, some // hacking is needed to modify the num_identify_calls_ instance variable. int* num_identify_calls_ptr = const_cast<int*>(&num_identify_calls_);
diff --git a/chromeos/services/secure_channel/fake_background_eid_generator.h b/chromeos/services/secure_channel/fake_background_eid_generator.h index 0605cad..60850a2 100644 --- a/chromeos/services/secure_channel/fake_background_eid_generator.h +++ b/chromeos/services/secure_channel/fake_background_eid_generator.h
@@ -30,8 +30,7 @@ const std::vector<cryptauth::BeaconSeed>& beacon_seed) const override; std::string IdentifyRemoteDeviceByAdvertisement( const std::string& advertisement_service_data, - const chromeos::multidevice::RemoteDeviceRefList& remote_devices) - const override; + const multidevice::RemoteDeviceRefList& remote_devices) const override; void set_nearest_eids_( std::unique_ptr<std::vector<DataWithTimestamp>> nearest_eids) {
diff --git a/chromeos/services/secure_channel/fake_ble_advertisement_generator.cc b/chromeos/services/secure_channel/fake_ble_advertisement_generator.cc index 0b66d054..d41c6a0b 100644 --- a/chromeos/services/secure_channel/fake_ble_advertisement_generator.cc +++ b/chromeos/services/secure_channel/fake_ble_advertisement_generator.cc
@@ -16,7 +16,7 @@ std::unique_ptr<DataWithTimestamp> FakeBleAdvertisementGenerator::GenerateBleAdvertisementInternal( - chromeos::multidevice::RemoteDeviceRef remote_device, + multidevice::RemoteDeviceRef remote_device, const std::string& local_device_public_key) { return std::move(advertisement_); }
diff --git a/chromeos/services/secure_channel/fake_ble_advertisement_generator.h b/chromeos/services/secure_channel/fake_ble_advertisement_generator.h index d2201bd..9e9e834 100644 --- a/chromeos/services/secure_channel/fake_ble_advertisement_generator.h +++ b/chromeos/services/secure_channel/fake_ble_advertisement_generator.h
@@ -29,7 +29,7 @@ protected: std::unique_ptr<DataWithTimestamp> GenerateBleAdvertisementInternal( - chromeos::multidevice::RemoteDeviceRef remote_device, + multidevice::RemoteDeviceRef remote_device, const std::string& local_device_public_key) override; private:
diff --git a/chromeos/services/secure_channel/fake_connection.cc b/chromeos/services/secure_channel/fake_connection.cc index d63e3f7a..ee4742a 100644 --- a/chromeos/services/secure_channel/fake_connection.cc +++ b/chromeos/services/secure_channel/fake_connection.cc
@@ -15,13 +15,11 @@ namespace secure_channel { -FakeConnection::FakeConnection( - chromeos::multidevice::RemoteDeviceRef remote_device) +FakeConnection::FakeConnection(multidevice::RemoteDeviceRef remote_device) : FakeConnection(remote_device, /* should_auto_connect */ true) {} -FakeConnection::FakeConnection( - chromeos::multidevice::RemoteDeviceRef remote_device, - bool should_auto_connect) +FakeConnection::FakeConnection(multidevice::RemoteDeviceRef remote_device, + bool should_auto_connect) : Connection(remote_device), should_auto_connect_(should_auto_connect) { if (should_auto_connect_) { Connect();
diff --git a/chromeos/services/secure_channel/fake_connection.h b/chromeos/services/secure_channel/fake_connection.h index b0a3950..7ed55ed 100644 --- a/chromeos/services/secure_channel/fake_connection.h +++ b/chromeos/services/secure_channel/fake_connection.h
@@ -18,8 +18,8 @@ // A fake implementation of Connection to use in tests. class FakeConnection : public Connection { public: - FakeConnection(chromeos::multidevice::RemoteDeviceRef remote_device); - FakeConnection(chromeos::multidevice::RemoteDeviceRef remote_device, + FakeConnection(multidevice::RemoteDeviceRef remote_device); + FakeConnection(multidevice::RemoteDeviceRef remote_device, bool should_auto_connect); ~FakeConnection() override;
diff --git a/chromeos/services/secure_channel/foreground_eid_generator.cc b/chromeos/services/secure_channel/foreground_eid_generator.cc index 05403d5..b61a6c5 100644 --- a/chromeos/services/secure_channel/foreground_eid_generator.cc +++ b/chromeos/services/secure_channel/foreground_eid_generator.cc
@@ -131,7 +131,7 @@ for (const auto& device_id : device_ids) { std::vector<std::string> possible_advertisements = GeneratePossibleAdvertisements( - chromeos::multidevice::RemoteDeviceRef::DerivePublicKey(device_id), + multidevice::RemoteDeviceRef::DerivePublicKey(device_id), scanning_device_beacon_seeds); for (const auto& possible_advertisement : possible_advertisements) { if (service_data_without_flags == possible_advertisement) {
diff --git a/chromeos/services/secure_channel/foreground_eid_generator_unittest.cc b/chromeos/services/secure_channel/foreground_eid_generator_unittest.cc index 6e2f849..1f933ad 100644 --- a/chromeos/services/secure_channel/foreground_eid_generator_unittest.cc +++ b/chromeos/services/secure_channel/foreground_eid_generator_unittest.cc
@@ -544,9 +544,8 @@ GenerateFakeAdvertisement(kSecondSeed, kDefaultCurrentPeriodStart, kDefaultAdvertisingDevicePublicKey); - std::string device_id = - chromeos::multidevice::RemoteDeviceRef::GenerateDeviceId( - kDefaultAdvertisingDevicePublicKey); + std::string device_id = multidevice::RemoteDeviceRef::GenerateDeviceId( + kDefaultAdvertisingDevicePublicKey); std::vector<std::string> device_id_list = {device_id}; std::string identified_device_id = eid_generator_->IdentifyRemoteDeviceByAdvertisement( @@ -567,9 +566,8 @@ service_data.append( 1, static_cast<char>(ForegroundEidGenerator::kBluetooth4Flag)); - std::string device_id = - chromeos::multidevice::RemoteDeviceRef::GenerateDeviceId( - kDefaultAdvertisingDevicePublicKey); + std::string device_id = multidevice::RemoteDeviceRef::GenerateDeviceId( + kDefaultAdvertisingDevicePublicKey); std::vector<std::string> device_id_list = {device_id}; std::string identified_device_id = eid_generator_->IdentifyRemoteDeviceByAdvertisement( @@ -589,9 +587,8 @@ // after the first 4 bytes. service_data.append("extra_flag_bytes"); - std::string device_id = - chromeos::multidevice::RemoteDeviceRef::GenerateDeviceId( - kDefaultAdvertisingDevicePublicKey); + std::string device_id = multidevice::RemoteDeviceRef::GenerateDeviceId( + kDefaultAdvertisingDevicePublicKey); std::vector<std::string> device_id_list = {device_id}; std::string identified_device_id = eid_generator_->IdentifyRemoteDeviceByAdvertisement( @@ -622,9 +619,8 @@ GenerateFakeAdvertisement(kSecondSeed, kDefaultCurrentPeriodStart, kDefaultAdvertisingDevicePublicKey); - std::string device_id = - chromeos::multidevice::RemoteDeviceRef::GenerateDeviceId( - kDefaultAdvertisingDevicePublicKey); + std::string device_id = multidevice::RemoteDeviceRef::GenerateDeviceId( + kDefaultAdvertisingDevicePublicKey); std::vector<std::string> device_id_list = {device_id, "wrongDeviceId"}; std::string identified_device_id = eid_generator_->IdentifyRemoteDeviceByAdvertisement(
diff --git a/chromeos/services/secure_channel/secure_channel_service.h b/chromeos/services/secure_channel/secure_channel_service.h index 70a7688..e76b2bb2 100644 --- a/chromeos/services/secure_channel/secure_channel_service.h +++ b/chromeos/services/secure_channel/secure_channel_service.h
@@ -19,9 +19,9 @@ class SecureChannelBase; -// Service which provides an implementation for -// secure_channel::mojom::SecureChannel. This service creates one -// implementation and shares it among all connection requests. +// Service which provides an implementation for mojom::SecureChannel. This +// service creates one implementation and shares it among all connection +// requests. class SecureChannelService : public service_manager::Service { public: explicit SecureChannelService(service_manager::mojom::ServiceRequest request);
diff --git a/chromeos/services/secure_channel/secure_channel_unittest.cc b/chromeos/services/secure_channel/secure_channel_unittest.cc index cc5fa26f..34487c2 100644 --- a/chromeos/services/secure_channel/secure_channel_unittest.cc +++ b/chromeos/services/secure_channel/secure_channel_unittest.cc
@@ -147,9 +147,9 @@ Authenticator* last_instance_; }; -chromeos::multidevice::RemoteDeviceRef CreateTestRemoteDevice() { - chromeos::multidevice::RemoteDeviceRef remote_device = - chromeos::multidevice::CreateRemoteDeviceRefListForTest(1)[0]; +multidevice::RemoteDeviceRef CreateTestRemoteDevice() { + multidevice::RemoteDeviceRef remote_device = + multidevice::CreateRemoteDeviceRefListForTest(1)[0]; return remote_device; } @@ -357,7 +357,7 @@ std::unique_ptr<TestAuthenticatorFactory> test_authenticator_factory_; - const chromeos::multidevice::RemoteDeviceRef test_device_; + const multidevice::RemoteDeviceRef test_device_; base::Optional<int32_t> rssi_;
diff --git a/components/BUILD.gn b/components/BUILD.gn index aaecf45..262a736 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -6,6 +6,7 @@ import("//build/config/features.gni") import("//build/config/ui.gni") import("//components/nacl/features.gni") +import("//components/ui_devtools/devtools.gni") import("//media/media_options.gni") import("//ppapi/buildflags/buildflags.gni") import("//printing/buildflags/buildflags.gni") @@ -183,6 +184,10 @@ ] } + if (use_viz_devtools) { + deps += [ "//components/ui_devtools/viz_views:unit_tests" ] + } + if (enable_nacl) { deps += [ "//components/nacl/browser:unit_tests" ] }
diff --git a/components/cronet/tools/cr_cronet.py b/components/cronet/tools/cr_cronet.py index 50a1c37..e7e6fe6 100755 --- a/components/cronet/tools/cr_cronet.py +++ b/components/cronet/tools/cr_cronet.py
@@ -160,7 +160,8 @@ test_target = 'cronet_test_instrumentation_apk' unit_target = 'cronet_unittests_android' gn_args = get_mobile_gn_args('android', options.release) + \ - 'use_errorprone_java_compiler=true enable_reporting=true ' + 'use_errorprone_java_compiler=true enable_reporting=true ' + \ + 'use_hashed_jni_names=true ' gn_extra = '' out_dir_suffix = '' if options.x86:
diff --git a/components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl.cc b/components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl.cc index b893000..5302c9c 100644 --- a/components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl.cc +++ b/components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl.cc
@@ -131,6 +131,12 @@ timing.page_end_time.value()) .release()); } + if (timing.navigation_start_to_main_frame_fetch_start) { + request->set_allocated_navigation_start_to_main_frame_fetch_start( + protobuf_parser::CreateDurationFromTimeDelta( + timing.navigation_start_to_main_frame_fetch_start.value()) + .release()); + } // Only set the lite page info if both the penalty and status have values. if (timing.lite_page_redirect_penalty.has_value() && timing.lite_page_redirect_status.has_value()) { @@ -143,10 +149,6 @@ protobuf_parser::ProtoLitePageRedirectStatusFromLitePageRedirectStatus( timing.lite_page_redirect_status.value())); } - request->set_allocated_navigation_start_to_main_frame_fetch_start( - protobuf_parser::CreateDurationFromTimeDelta( - timing.navigation_start_to_main_frame_fetch_start) - .release()); request->set_effective_connection_type( protobuf_parser::ProtoEffectiveConnectionTypeFromEffectiveConnectionType(
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.cc index aa6de4b..02c1da9 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.cc +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.cc
@@ -21,7 +21,8 @@ const base::Optional<base::TimeDelta>& lite_page_redirect_penalty, const base::Optional<previews::ServerLitePageStatus>& lite_page_redirect_status, - const base::TimeDelta& navigation_start_to_main_frame_fetch_start, + const base::Optional<base::TimeDelta>& + navigation_start_to_main_frame_fetch_start, int64_t network_bytes, int64_t original_network_bytes, int64_t total_page_size_bytes,
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.h index 9eb0f62..3f649ba 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.h +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.h
@@ -32,7 +32,8 @@ const base::Optional<base::TimeDelta>& lite_page_redirect_penalty, const base::Optional<previews::ServerLitePageStatus>& lite_page_redirect_status, - const base::TimeDelta& navigation_start_to_main_frame_fetch_start, + const base::Optional<base::TimeDelta>& + navigation_start_to_main_frame_fetch_start, int64_t network_bytes, int64_t original_network_bytes, int64_t total_page_size_bytes, @@ -80,7 +81,8 @@ lite_page_redirect_status; // The duration between the navigation start as reported by the navigation // handle, and when the fetchStart of the main page HTML. - const base::TimeDelta navigation_start_to_main_frame_fetch_start; + const base::Optional<base::TimeDelta> + navigation_start_to_main_frame_fetch_start; // The number of bytes served over the network, not including headers. const int64_t network_bytes;
diff --git a/components/download/quarantine/quarantine_linux.cc b/components/download/quarantine/quarantine_linux.cc index 42ce31e..8683056 100644 --- a/components/download/quarantine/quarantine_linux.cc +++ b/components/download/quarantine/quarantine_linux.cc
@@ -23,6 +23,9 @@ const char* value, size_t value_size, int flags) { +// On Chrome OS, there is no component that can validate these extended +// attributes so there is no need to set them. +#if !defined(OS_CHROMEOS) base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK); int result = setxattr(path, name, value, value_size, flags); if (result) { @@ -30,6 +33,7 @@ << path; return false; } +#endif // !defined(OS_CHROMEOS) return true; }
diff --git a/components/download/quarantine/quarantine_linux_unittest.cc b/components/download/quarantine/quarantine_linux_unittest.cc index 0210485..3216420 100644 --- a/components/download/quarantine/quarantine_linux_unittest.cc +++ b/components/download/quarantine/quarantine_linux_unittest.cc
@@ -50,12 +50,14 @@ protected: void SetUp() override { +#if !defined(OS_CHROMEOS) ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); ASSERT_TRUE( base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &test_file_)); int result = setxattr(test_file_.value().c_str(), "user.test", "test", 4, 0); is_xattr_supported_ = (!result) || (errno != ENOTSUP); +#endif // !defined(OS_CHROMEOS) if (!is_xattr_supported_) { LOG(WARNING) << "Test will be skipped because extended attributes are " "not supported on this OS/file system.";
diff --git a/components/drive/chromeos/about_resource_root_folder_id_loader.cc b/components/drive/chromeos/about_resource_root_folder_id_loader.cc index 441586c..c561aba 100644 --- a/components/drive/chromeos/about_resource_root_folder_id_loader.cc +++ b/components/drive/chromeos/about_resource_root_folder_id_loader.cc
@@ -22,8 +22,12 @@ const RootFolderIdCallback& callback) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - // After the initial load GetAboutResource will just return the cached value, - // avoiding any network calls. + // If we have already read the root folder id, then we can simply return it. + if (!root_folder_id_.empty()) { + callback.Run(FILE_ERROR_OK, root_folder_id_); + return; + } + about_resource_loader_->GetAboutResource( base::BindRepeating(&AboutResourceRootFolderIdLoader::OnGetAboutResource, weak_ptr_factory_.GetWeakPtr(), callback)); @@ -43,7 +47,9 @@ DCHECK(about_resource); - callback.Run(error, about_resource->root_folder_id()); + // The root folder id is immutable so we can save it for subsequent calls. + root_folder_id_ = about_resource->root_folder_id(); + callback.Run(error, root_folder_id_); } } // namespace internal
diff --git a/components/drive/chromeos/about_resource_root_folder_id_loader.h b/components/drive/chromeos/about_resource_root_folder_id_loader.h index dbcfff4..71cd6ff8 100644 --- a/components/drive/chromeos/about_resource_root_folder_id_loader.h +++ b/components/drive/chromeos/about_resource_root_folder_id_loader.h
@@ -41,6 +41,7 @@ std::unique_ptr<google_apis::AboutResource> about_resource); AboutResourceLoader* about_resource_loader_; // Not owned. + std::string root_folder_id_; THREAD_CHECKER(thread_checker_);
diff --git a/components/feed/core/feed_logging_metrics.cc b/components/feed/core/feed_logging_metrics.cc index 63263a7..908a6f2b 100644 --- a/components/feed/core/feed_logging_metrics.cc +++ b/components/feed/core/feed_logging_metrics.cc
@@ -93,6 +93,11 @@ suggestions_count, kMaxSuggestionsTotal); } +void FeedLoggingMetrics::OnPagePopulated(base::TimeDelta timeToPopulate) { + UMA_HISTOGRAM_MEDIUM_TIMES("ContentSuggestions.Feed.PagePopulatingTime", + timeToPopulate); +} + void FeedLoggingMetrics::OnSuggestionShown(int position, base::Time publish_date, float score,
diff --git a/components/feed/core/feed_logging_metrics.h b/components/feed/core/feed_logging_metrics.h index abb42d1..994d19f 100644 --- a/components/feed/core/feed_logging_metrics.h +++ b/components/feed/core/feed_logging_metrics.h
@@ -42,6 +42,10 @@ // depend on whether the user actually saw the cards. void OnPageShown(const int suggestions_count); + // The amount of time for the Feed to populate articles. This does not include + // time to render but time to populate data in the UI. + void OnPagePopulated(base::TimeDelta timeToPopulate); + // Should only be called once per NTP for each suggestion. void OnSuggestionShown(int position, base::Time publish_date,
diff --git a/components/image_fetcher/core/cached_image_fetcher.cc b/components/image_fetcher/core/cached_image_fetcher.cc index b2dd80d..b6a5ddf 100644 --- a/components/image_fetcher/core/cached_image_fetcher.cc +++ b/components/image_fetcher/core/cached_image_fetcher.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/metrics/histogram_macros.h" +#include "base/task/post_task.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/timer/elapsed_timer.h" #include "components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter.h" @@ -15,12 +16,36 @@ #include "components/image_fetcher/core/image_decoder.h" #include "components/image_fetcher/core/request_metadata.h" #include "ui/gfx/codec/png_codec.h" -#include "ui/gfx/geometry/size.h" #include "ui/gfx/image/image.h" #include "ui/gfx/image/image_skia.h" namespace image_fetcher { +struct CachedImageFetcherRequest { + // The url to be fetched. + const GURL url; + + // An identifier passed back to the caller. + const std::string id; + + // The desired frame size if there are multiple frames to choose from. + const gfx::Size desired_frame_size; + + // The service to track data usage for. + const DataUseServiceName data_use_service_name; + + // Limit the number of bytes to download for the image. + const base::Optional<int64_t> image_download_limit_bytes; + + // Analytic events below. + + // True if there was a cache hit during the fetch sequence. + bool cache_hit_before_network_request; + + // The start time of the fetch sequence. + const base::Time start_time; +}; + namespace { void DataCallbackIfPresent(ImageDataFetcherCallback data_callback, @@ -42,7 +67,7 @@ std::move(image_callback).Run(id, image, metadata); } -std::string EncodeSkBitmapToPNG(SkBitmap bitmap) { +std::string EncodeSkBitmapToPNG(const SkBitmap& bitmap) { std::vector<unsigned char> encoded_data; bool result = gfx::PNGCodec::Encode( static_cast<const unsigned char*>(bitmap.getPixels()), @@ -70,16 +95,16 @@ void CachedImageFetcher::SetDataUseServiceName( DataUseServiceName data_use_service_name) { - image_fetcher_->SetDataUseServiceName(data_use_service_name); + data_use_service_name_ = data_use_service_name; } void CachedImageFetcher::SetDesiredImageFrameSize(const gfx::Size& size) { - desired_image_frame_size_ = size; + desired_frame_size_ = size; } void CachedImageFetcher::SetImageDownloadLimit( base::Optional<int64_t> max_download_bytes) { - image_fetcher_->SetImageDownloadLimit(max_download_bytes); + image_download_limit_bytes_ = max_download_bytes; } ImageDecoder* CachedImageFetcher::GetImageDecoder() { @@ -89,190 +114,166 @@ void CachedImageFetcher::FetchImageAndData( const std::string& id, const GURL& image_url, - ImageDataFetcherCallback data_callback, + ImageDataFetcherCallback image_data_callback, ImageFetcherCallback image_callback, const net::NetworkTrafficAnnotationTag& traffic_annotation) { + // TODO(wylieb): Inject a clock for better testability. + CachedImageFetcherRequest request = { + image_url, + id, + desired_frame_size_, + data_use_service_name_, + image_download_limit_bytes_, + /* cache_hit_before_network_request */ false, + /* start_time */ base::Time::Now()}; + // First, try to load the image from the cache, then try the network. image_cache_->LoadImage( read_only_, image_url.spec(), base::BindOnce(&CachedImageFetcher::OnImageFetchedFromCache, - weak_ptr_factory_.GetWeakPtr(), base::Time::Now(), - desired_image_frame_size_, id, image_url, - std::move(data_callback), std::move(image_callback), - traffic_annotation)); + weak_ptr_factory_.GetWeakPtr(), std::move(request), + traffic_annotation, std::move(image_data_callback), + std::move(image_callback))); CachedImageFetcherMetricsReporter::ReportEvent( CachedImageFetcherEvent::kImageRequest); } void CachedImageFetcher::OnImageFetchedFromCache( - base::Time start_time, - const gfx::Size& size, - const std::string& id, - const GURL& image_url, - ImageDataFetcherCallback data_callback, - ImageFetcherCallback image_callback, + CachedImageFetcherRequest request, const net::NetworkTrafficAnnotationTag& traffic_annotation, + ImageDataFetcherCallback image_data_callback, + ImageFetcherCallback image_callback, std::string image_data) { if (image_data.empty()) { // Fetching from the DB failed, start a network fetch. - EnqueueFetchImageFromNetwork(/* cache_hit */ false, start_time, size, id, - image_url, std::move(data_callback), - std::move(image_callback), traffic_annotation); + EnqueueFetchImageFromNetwork(std::move(request), traffic_annotation, + std::move(image_data_callback), + std::move(image_callback)); CachedImageFetcherMetricsReporter::ReportEvent( CachedImageFetcherEvent::kCacheMiss); } else { - DataCallbackIfPresent(std::move(data_callback), image_data, + DataCallbackIfPresent(std::move(image_data_callback), image_data, RequestMetadata()); - // TODO(wylieb): On Android, do this in-process. GetImageDecoder()->DecodeImage( - image_data, size, - base::BindRepeating(&CachedImageFetcher::OnImageDecodedFromCache, - weak_ptr_factory_.GetWeakPtr(), start_time, size, - id, image_url, - base::Passed(std::move(data_callback)), - base::Passed(std::move(image_callback)), - traffic_annotation, image_data)); + image_data, + /* The frame size had already been chosen during fetch. */ gfx::Size(), + base::BindRepeating( + &CachedImageFetcher::OnImageDecodedFromCache, + weak_ptr_factory_.GetWeakPtr(), std::move(request), + traffic_annotation, base::Passed(std::move(image_data_callback)), + base::Passed(std::move(image_callback)), image_data)); CachedImageFetcherMetricsReporter::ReportEvent( CachedImageFetcherEvent::kCacheHit); } } void CachedImageFetcher::OnImageDecodedFromCache( - base::Time start_time, - const gfx::Size& size, - const std::string& id, - const GURL& image_url, - ImageDataFetcherCallback data_callback, - ImageFetcherCallback image_callback, + CachedImageFetcherRequest request, const net::NetworkTrafficAnnotationTag& traffic_annotation, + ImageDataFetcherCallback image_data_callback, + ImageFetcherCallback image_callback, const std::string& image_data, const gfx::Image& image) { if (image.IsEmpty()) { // Upon failure, fetch from the network. - EnqueueFetchImageFromNetwork(/* cache_hit */ true, start_time, size, id, - image_url, std::move(data_callback), - std::move(image_callback), traffic_annotation); + request.cache_hit_before_network_request = true; + EnqueueFetchImageFromNetwork(std::move(request), traffic_annotation, + std::move(image_data_callback), + std::move(image_callback)); CachedImageFetcherMetricsReporter::ReportEvent( CachedImageFetcherEvent::kCacheDecodingError); } else { - ImageCallbackIfPresent(std::move(image_callback), id, image, + ImageCallbackIfPresent(std::move(image_callback), request.id, image, RequestMetadata()); - CachedImageFetcherMetricsReporter::ReportImageLoadFromCacheTime(start_time); + CachedImageFetcherMetricsReporter::ReportImageLoadFromCacheTime( + request.start_time); } } void CachedImageFetcher::EnqueueFetchImageFromNetwork( - bool cache_hit, - base::Time start_time, - const gfx::Size& size, - const std::string& id, - const GURL& image_url, - ImageDataFetcherCallback data_callback, - ImageFetcherCallback image_callback, - const net::NetworkTrafficAnnotationTag& traffic_annotation) { + CachedImageFetcherRequest request, + const net::NetworkTrafficAnnotationTag& traffic_annotation, + ImageDataFetcherCallback image_data_callback, + ImageFetcherCallback image_callback) { base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&CachedImageFetcher::FetchImageFromNetwork, - weak_ptr_factory_.GetWeakPtr(), cache_hit, start_time, - size, id, image_url, std::move(data_callback), - std::move(image_callback), traffic_annotation)); + weak_ptr_factory_.GetWeakPtr(), std::move(request), + traffic_annotation, std::move(image_data_callback), + std::move(image_callback))); } void CachedImageFetcher::FetchImageFromNetwork( - bool cache_hit, - base::Time start_time, - const gfx::Size& size, - const std::string& id, - const GURL& image_url, - ImageDataFetcherCallback data_callback, - ImageFetcherCallback image_callback, - const net::NetworkTrafficAnnotationTag& traffic_annotation) { + CachedImageFetcherRequest request, + const net::NetworkTrafficAnnotationTag& traffic_annotation, + ImageDataFetcherCallback image_data_callback, + ImageFetcherCallback image_callback) { + std::string id = request.id; + const GURL& url = request.url; // Fetch image data and the image itself. The image data will be stored in // the image cache, and the image will be returned to the caller. - image_fetcher_->SetDesiredImageFrameSize(size); + image_fetcher_->SetDesiredImageFrameSize(request.desired_frame_size); + image_fetcher_->SetDataUseServiceName(request.data_use_service_name); + image_fetcher_->SetImageDownloadLimit(request.image_download_limit_bytes); image_fetcher_->FetchImageAndData( - id, image_url, - base::BindOnce(&CachedImageFetcher::DecodeDataForCaching, - weak_ptr_factory_.GetWeakPtr(), std::move(data_callback), - image_url), + id, url, std::move(image_data_callback), base::BindOnce(&CachedImageFetcher::OnImageFetchedFromNetwork, - weak_ptr_factory_.GetWeakPtr(), cache_hit, start_time, - std::move(image_callback), image_url), + weak_ptr_factory_.GetWeakPtr(), std::move(request), + std::move(image_callback)), traffic_annotation); } void CachedImageFetcher::OnImageFetchedFromNetwork( - bool cache_hit, - base::Time start_time, + CachedImageFetcherRequest request, ImageFetcherCallback image_callback, - const GURL& image_url, const std::string& id, const gfx::Image& image, const RequestMetadata& request_metadata) { // The image has been deocded by the fetcher already, return straight to the // caller. - ImageCallbackIfPresent(std::move(image_callback), id, image, + ImageCallbackIfPresent(std::move(image_callback), request.id, image, request_metadata); - // Report failure if the image is empty. - if (image.IsEmpty()) { + // Copy the image data out and store it on disk. + const SkBitmap* bitmap = image.IsEmpty() ? nullptr : image.ToSkBitmap(); + // If the bitmap is null or otherwise not ready, skip encoding. + if (bitmap == nullptr || bitmap->isNull() || !bitmap->readyToDraw()) { + StoreEncodedData(request.url, ""); CachedImageFetcherMetricsReporter::ReportEvent( CachedImageFetcherEvent::kTotalFailure); + } else { + // Post a task to another thread to encode the image data downloaded. + base::PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce(&EncodeSkBitmapToPNG, *bitmap), + base::BindOnce(&CachedImageFetcher::StoreEncodedData, + weak_ptr_factory_.GetWeakPtr(), request.url)); } // Report to different histograms depending upon if there was a cache hit. - if (cache_hit) { + if (request.cache_hit_before_network_request) { CachedImageFetcherMetricsReporter::ReportImageLoadFromNetworkAfterCacheHit( - start_time); + request.start_time); } else { CachedImageFetcherMetricsReporter::ReportImageLoadFromNetworkTime( - start_time); + request.start_time); } } -void CachedImageFetcher::DecodeDataForCaching( - ImageDataFetcherCallback data_callback, - const GURL& image_url, - const std::string& image_data, - const RequestMetadata& request_metadata) { - DataCallbackIfPresent(std::move(data_callback), image_data, request_metadata); - GetImageDecoder()->DecodeImage( - image_data, /* Decoding for cache shouldn't specify size */ gfx::Size(), - base::BindRepeating(&CachedImageFetcher::StartEncodingDataAndCache, - weak_ptr_factory_.GetWeakPtr(), image_url)); -} - -void CachedImageFetcher::StartEncodingDataAndCache(const GURL& image_url, - const gfx::Image& image) { - SkBitmap bitmap = image.IsEmpty() ? SkBitmap() : *image.ToSkBitmap(); - // If the bitmap is null or otherwise not ready, skip encoding. - if (!bitmap.readyToDraw() || bitmap.isNull()) { - StoreEncodedData(image_url, ""); - return; - } - - // Post a task to another thread to encode the image data downloaded. - base::PostTaskAndReplyWithResult( - FROM_HERE, base::BindOnce(&EncodeSkBitmapToPNG, std::move(bitmap)), - base::BindOnce(&CachedImageFetcher::StoreEncodedData, - weak_ptr_factory_.GetWeakPtr(), image_url)); -} - -void CachedImageFetcher::StoreEncodedData(const GURL& image_url, +void CachedImageFetcher::StoreEncodedData(const GURL& url, std::string image_data) { // If the image is empty, delete the image. if (image_data.empty()) { CachedImageFetcherMetricsReporter::ReportEvent( CachedImageFetcherEvent::kTranscodingError); - image_cache_->DeleteImage(image_url.spec()); + image_cache_->DeleteImage(url.spec()); return; } if (!read_only_) { - image_cache_->SaveImage(image_url.spec(), std::move(image_data)); + image_cache_->SaveImage(url.spec(), std::move(image_data)); } }
diff --git a/components/image_fetcher/core/cached_image_fetcher.h b/components/image_fetcher/core/cached_image_fetcher.h index 9464830..f40f574 100644 --- a/components/image_fetcher/core/cached_image_fetcher.h +++ b/components/image_fetcher/core/cached_image_fetcher.h
@@ -9,11 +9,7 @@ #include <string> #include <vector> -#include "base/containers/flat_map.h" #include "base/memory/weak_ptr.h" -#include "base/task/post_task.h" -#include "base/timer/timer.h" -#include "components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter.h" #include "components/image_fetcher/core/image_decoder.h" #include "components/image_fetcher/core/image_fetcher.h" #include "components/image_fetcher/core/image_fetcher_types.h" @@ -21,18 +17,15 @@ #include "ui/gfx/geometry/size.h" #include "url/gurl.h" -namespace gfx { -class Image; -class Size; -} // namespace gfx - namespace image_fetcher { class ImageCache; class ImageFetcher; struct RequestMetadata; -// TODO(wylieb): Consider creating a struct to encapsulate the request. +// Encapsulates a request to simplify argument lists. +struct CachedImageFetcherRequest; + // CachedImageFetcher takes care of fetching images from the network and caching // them. Has a read-only mode which doesn't perform write operations on the // cache. @@ -59,58 +52,36 @@ private: // Cache void OnImageFetchedFromCache( - base::Time start_time, - const gfx::Size& size, - const std::string& id, - const GURL& image_url, + CachedImageFetcherRequest request, + const net::NetworkTrafficAnnotationTag& traffic_annotation, ImageDataFetcherCallback image_data_callback, ImageFetcherCallback image_callback, - const net::NetworkTrafficAnnotationTag& traffic_annotation, std::string image_data); void OnImageDecodedFromCache( - base::Time start_time, - const gfx::Size& size, - const std::string& id, - const GURL& image_url, + CachedImageFetcherRequest request, + const net::NetworkTrafficAnnotationTag& traffic_annotation, ImageDataFetcherCallback image_data_callback, ImageFetcherCallback image_callback, - const net::NetworkTrafficAnnotationTag& traffic_annotation, const std::string& image_data, const gfx::Image& image); // Network void EnqueueFetchImageFromNetwork( - bool cache_hit, - base::Time start_time, - const gfx::Size& size, - const std::string& id, - const GURL& image_url, + CachedImageFetcherRequest request, + const net::NetworkTrafficAnnotationTag& traffic_annotation, ImageDataFetcherCallback image_data_callback, - ImageFetcherCallback image_callback, - const net::NetworkTrafficAnnotationTag& traffic_annotation); + ImageFetcherCallback image_callback); void FetchImageFromNetwork( - bool cache_hit, - base::Time start_time, - const gfx::Size& size, - const std::string& id, - const GURL& image_url, + CachedImageFetcherRequest request, + const net::NetworkTrafficAnnotationTag& traffic_annotation, ImageDataFetcherCallback image_data_callback, - ImageFetcherCallback image_callback, - const net::NetworkTrafficAnnotationTag& traffic_annotation); - void OnImageFetchedFromNetwork(bool cache_hit, - base::Time start_time, + ImageFetcherCallback image_callback); + void OnImageFetchedFromNetwork(CachedImageFetcherRequest request, ImageFetcherCallback image_callback, - const GURL& image_url, const std::string& id, const gfx::Image& image, const RequestMetadata& request_metadata); - void DecodeDataForCaching(ImageDataFetcherCallback image_data_callback, - const GURL& image_url, - const std::string& image_data, - const RequestMetadata& request_metadata); - void StartEncodingDataAndCache(const GURL& image_url, - const gfx::Image& image); - void StoreEncodedData(const GURL& image_url, std::string image_data); + void StoreEncodedData(const GURL& url, std::string image_data); // Whether the ImageChache is allowed to be modified in any way from requests // made by this CachedImageFetcher. This includes updating last used times, @@ -124,7 +95,10 @@ // When true, operations won't affect the longeivity of valid cache items. bool read_only_; - gfx::Size desired_image_frame_size_; + // Capture parameters when ImageFetcher Set* methods are called. + gfx::Size desired_frame_size_; + DataUseServiceName data_use_service_name_; + base::Optional<int64_t> image_download_limit_bytes_; base::WeakPtrFactory<CachedImageFetcher> weak_ptr_factory_;
diff --git a/components/image_fetcher/core/cached_image_fetcher_unittest.cc b/components/image_fetcher/core/cached_image_fetcher_unittest.cc index aaf3f73..1e46e64 100644 --- a/components/image_fetcher/core/cached_image_fetcher_unittest.cc +++ b/components/image_fetcher/core/cached_image_fetcher_unittest.cc
@@ -18,6 +18,7 @@ #include "base/test/scoped_task_environment.h" #include "base/test/simple_test_clock.h" #include "base/threading/sequenced_task_runner_handle.h" +#include "components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter.h" #include "components/image_fetcher/core/cache/image_cache.h" #include "components/image_fetcher/core/cache/image_data_store_disk.h" #include "components/image_fetcher/core/cache/image_metadata_store_leveldb.h"
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn index 331aded..1b8eb957 100644 --- a/components/metrics/BUILD.gn +++ b/components/metrics/BUILD.gn
@@ -15,6 +15,8 @@ "client_info.h", "cloned_install_detector.cc", "cloned_install_detector.h", + "cpu_metrics_provider.cc", + "cpu_metrics_provider.h", "daily_event.cc", "daily_event.h", "data_use_tracker.cc",
diff --git a/components/metrics/cpu_metrics_provider.cc b/components/metrics/cpu_metrics_provider.cc new file mode 100644 index 0000000..93af571 --- /dev/null +++ b/components/metrics/cpu_metrics_provider.cc
@@ -0,0 +1,28 @@ +// 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/metrics/cpu_metrics_provider.h" + +#include "base/cpu.h" +#include "base/system/sys_info.h" +#include "third_party/metrics_proto/system_profile.pb.h" + +namespace metrics { + +CPUMetricsProvider::CPUMetricsProvider() {} + +CPUMetricsProvider::~CPUMetricsProvider() {} + +void CPUMetricsProvider::ProvideSystemProfileMetrics( + SystemProfileProto* system_profile) { + SystemProfileProto::Hardware::CPU* cpu = + system_profile->mutable_hardware()->mutable_cpu(); + // All the CPU information is generated in the constructor. + base::CPU cpu_info; + cpu->set_vendor_name(cpu_info.vendor_name()); + cpu->set_signature(cpu_info.signature()); + cpu->set_num_cores(base::SysInfo::NumberOfProcessors()); +} + +} // namespace metrics
diff --git a/components/metrics/cpu_metrics_provider.h b/components/metrics/cpu_metrics_provider.h new file mode 100644 index 0000000..067822b --- /dev/null +++ b/components/metrics/cpu_metrics_provider.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 COMPONENTS_METRICS_CPU_METRICS_PROVIDER_H_ +#define COMPONENTS_METRICS_CPU_METRICS_PROVIDER_H_ + +#include "base/macros.h" +#include "components/metrics/metrics_provider.h" + +namespace metrics { + +// CPUMetricsProvider adds CPU Info in the system profile. These include +// CPU vendor information, cpu cores, etc. This doesn't provide CPU usage +// information. +class CPUMetricsProvider : public MetricsProvider { + public: + CPUMetricsProvider(); + ~CPUMetricsProvider() override; + + void ProvideSystemProfileMetrics( + SystemProfileProto* system_profile_proto) override; + + private: + DISALLOW_COPY_AND_ASSIGN(CPUMetricsProvider); +}; + +} // namespace metrics + +#endif // COMPONENTS_METRICS_CPU_METRICS_PROVIDER_H_
diff --git a/components/metrics/metrics_log.cc b/components/metrics/metrics_log.cc index 5472d50a..18c6f9d7 100644 --- a/components/metrics/metrics_log.cc +++ b/components/metrics/metrics_log.cc
@@ -296,13 +296,6 @@ if (client_->GetBrand(&brand_code)) system_profile->set_brand_code(brand_code); - SystemProfileProto::Hardware::CPU* cpu = - system_profile->mutable_hardware()->mutable_cpu(); - base::CPU cpu_info; - cpu->set_vendor_name(cpu_info.vendor_name()); - cpu->set_signature(cpu_info.signature()); - cpu->set_num_cores(base::SysInfo::NumberOfProcessors()); - delegating_provider->ProvideSystemProfileMetrics(system_profile); return *system_profile;
diff --git a/components/metrics/metrics_log_unittest.cc b/components/metrics/metrics_log_unittest.cc index caf38d4..752991aa 100644 --- a/components/metrics/metrics_log_unittest.cc +++ b/components/metrics/metrics_log_unittest.cc
@@ -18,6 +18,7 @@ #include "base/strings/stringprintf.h" #include "base/system/sys_info.h" #include "base/time/time.h" +#include "components/metrics/cpu_metrics_provider.h" #include "components/metrics/delegating_provider.h" #include "components/metrics/environment_recorder.h" #include "components/metrics/metrics_pref_names.h" @@ -237,6 +238,8 @@ TestMetricsLog log(kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client); DelegatingProvider delegating_provider; + auto cpu_provider = std::make_unique<metrics::CPUMetricsProvider>(); + delegating_provider.RegisterMetricsProvider(std::move(cpu_provider)); log.RecordEnvironment(&delegating_provider); // Check that the system profile on the log has the correct values set. CheckSystemProfile(log.system_profile());
diff --git a/components/omnibox/browser/autocomplete_controller.cc b/components/omnibox/browser/autocomplete_controller.cc index 3bb7a0cc..bb7dc87 100644 --- a/components/omnibox/browser/autocomplete_controller.cc +++ b/components/omnibox/browser/autocomplete_controller.cc
@@ -219,11 +219,6 @@ providers_.push_back(new BuiltinProvider(provider_client_.get())); if (provider_types & AutocompleteProvider::TYPE_HISTORY_QUICK) providers_.push_back(new HistoryQuickProvider(provider_client_.get())); - if (provider_types & AutocompleteProvider::TYPE_HISTORY_URL) { - history_url_provider_ = - new HistoryURLProvider(provider_client_.get(), this); - providers_.push_back(history_url_provider_); - } if (provider_types & AutocompleteProvider::TYPE_KEYWORD) { keyword_provider_ = new KeywordProvider(provider_client_.get(), this); providers_.push_back(keyword_provider_); @@ -266,6 +261,25 @@ } } + // It's important that the HistoryURLProvider gets added last, or at least + // after SearchProvider: + // AutocompleteController::Start() calls each providers' Start() function + // synchronously in the order they're in in providers_. + // - SearchProvider::Start() synchronously queries the history database's + // keyword_search_terms and url table. + // - HistoryUrlProvider::Start schedules a background task that also accesses + // the history database. + // If both db accesses happen concurrently, TSan complains. + // So put HistoryURLProvider later to make sure that SearchProvider is done + // doing its thing by the time the HistoryURLProvider task runs. + // (And hope that it completes before AutocompleteController::Start() is + // called the next time.) + if (provider_types & AutocompleteProvider::TYPE_HISTORY_URL) { + history_url_provider_ = + new HistoryURLProvider(provider_client_.get(), this); + providers_.push_back(history_url_provider_); + } + base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( this, "AutocompleteController", base::ThreadTaskRunnerHandle::Get()); }
diff --git a/components/password_manager/core/browser/new_password_form_manager.cc b/components/password_manager/core/browser/new_password_form_manager.cc index 4cfed8d..bb0f525 100644 --- a/components/password_manager/core/browser/new_password_form_manager.cc +++ b/components/password_manager/core/browser/new_password_form_manager.cc
@@ -16,7 +16,6 @@ #include "components/password_manager/core/browser/browser_save_password_progress_logger.h" #include "components/password_manager/core/browser/form_fetcher_impl.h" #include "components/password_manager/core/browser/form_saver.h" -#include "components/password_manager/core/browser/password_form_filling.h" #include "components/password_manager/core/browser/password_manager_client.h" #include "components/password_manager/core/browser/password_manager_driver.h" #include "components/password_manager/core/browser/password_manager_util.h" @@ -596,10 +595,10 @@ // TODO(https://crbug.com/831123). Implement correct treating of federated // matches. std::vector<const PasswordForm*> federated_matches; - SendFillInformationToRenderer(*client_, driver_.get(), IsBlacklisted(), - *observed_password_form.get(), best_matches_, - federated_matches, preferred_match_, - metrics_recorder_.get()); + likely_form_filling_ = SendFillInformationToRenderer( + *client_, driver_.get(), IsBlacklisted(), *observed_password_form.get(), + best_matches_, federated_matches, preferred_match_, + metrics_recorder_.get()); } void NewPasswordFormManager::FillForm(const FormData& observed_form) { @@ -753,12 +752,14 @@ metrics_recorder_->SetUserAction(UserAction::kOverridePassword); } else { // In case |saved_form| is pointing to the same form as - // |preferred_match_|, the user either did not do anything, or - // re-selected the default option. Otherwise, the user purposefully - // chose an alternative. - metrics_recorder_->SetUserAction(saved_form == preferred_match_ - ? UserAction::kNone - : UserAction::kChoose); + // |preferred_match_| and the form was filled on page load, the user + // either did not do anything, or re-selected the default option. + // Otherwise, the user purposefully chose a credential. + metrics_recorder_->SetUserAction( + saved_form == preferred_match_ && + likely_form_filling_ == LikelyFormFilling::kFillOnPageLoad + ? UserAction::kNone + : UserAction::kChoose); } } } else if (!best_matches_.empty() &&
diff --git a/components/password_manager/core/browser/new_password_form_manager.h b/components/password_manager/core/browser/new_password_form_manager.h index 35c30172..4330458a 100644 --- a/components/password_manager/core/browser/new_password_form_manager.h +++ b/components/password_manager/core/browser/new_password_form_manager.h
@@ -18,6 +18,7 @@ #include "components/password_manager/core/browser/form_fetcher.h" #include "components/password_manager/core/browser/form_parsing/form_parser.h" #include "components/password_manager/core/browser/form_parsing/password_field_prediction.h" +#include "components/password_manager/core/browser/password_form_filling.h" #include "components/password_manager/core/browser/password_form_manager_for_ui.h" #include "components/password_manager/core/browser/password_form_metrics_recorder.h" #include "components/password_manager/core/browser/password_form_user_action.h" @@ -276,6 +277,9 @@ VotesUploader votes_uploader_; + // Probable filling mechanism used in the renderer for this password form. + LikelyFormFilling likely_form_filling_ = LikelyFormFilling::kNoFilling; + // |is_submitted_| = true means that a submission of the managed form was seen // and then |submitted_form_| contains the submitted form. bool is_submitted_ = false;
diff --git a/components/password_manager/core/browser/new_password_form_manager_unittest.cc b/components/password_manager/core/browser/new_password_form_manager_unittest.cc index a8cd073..f77fd7f5 100644 --- a/components/password_manager/core/browser/new_password_form_manager_unittest.cc +++ b/components/password_manager/core/browser/new_password_form_manager_unittest.cc
@@ -40,6 +40,7 @@ using testing::AllOf; using testing::Mock; using testing::NiceMock; +using testing::Return; using testing::SaveArg; using testing::SaveArgPointee; @@ -92,6 +93,8 @@ MockPasswordManagerClient() = default; ~MockPasswordManagerClient() override = default; + MOCK_CONST_METHOD0(IsIncognito, bool()); + MOCK_METHOD0(GetAutofillDownloadManager, autofill::AutofillDownloadManager*()); @@ -635,12 +638,20 @@ saved_match_.username_value; submitted_form_.fields[kPasswordFieldIndex].value = saved_match_.password_value; - EXPECT_TRUE( - form_manager_->ProvisionallySaveIfIsManaged(submitted_form_, &driver_)); - CheckPendingCredentials(/* expected */ saved_match_, - form_manager_->GetPendingCredentials()); - EXPECT_EQ(UserAction::kNone, - form_manager_->GetMetricsRecorder()->GetUserAction()); + + // Tests that depending on whether we fill on page load or account select that + // correct user action is recorded. Fill on account select is simulated by + // pretending we are in incognito mode. + for (bool is_incognito : {false, true}) { + EXPECT_CALL(client_, IsIncognito).WillOnce(Return(is_incognito)); + form_manager_->Fill(); + EXPECT_TRUE( + form_manager_->ProvisionallySaveIfIsManaged(submitted_form_, &driver_)); + CheckPendingCredentials(/* expected */ saved_match_, + form_manager_->GetPendingCredentials()); + EXPECT_EQ(is_incognito ? UserAction::kChoose : UserAction::kNone, + form_manager_->GetMetricsRecorder()->GetUserAction()); + } } // Tests that when submitted credentials are equal to already saved PSL
diff --git a/components/password_manager/core/browser/password_form_filling.cc b/components/password_manager/core/browser/password_form_filling.cc index daf2b95..069c08fc 100644 --- a/components/password_manager/core/browser/password_form_filling.cc +++ b/components/password_manager/core/browser/password_form_filling.cc
@@ -103,7 +103,7 @@ } // namespace -void SendFillInformationToRenderer( +LikelyFormFilling SendFillInformationToRenderer( const PasswordManagerClient& client, PasswordManagerDriver* driver, bool is_blacklisted, @@ -122,7 +122,7 @@ driver->InformNoSavedCredentials(); metrics_recorder->RecordFillEvent( PasswordFormMetricsRecorder::kManagerFillEventNoCredential); - return; + return LikelyFormFilling::kNoFilling; } DCHECK(preferred_match); @@ -136,9 +136,15 @@ // password field ID, then PasswordAutofillAgent has no way to fill the // password anywhere. const bool form_good_for_filling = - base::FeatureList::IsEnabled(features::kNewPasswordFormParsing) - ? true - : !observed_form.IsPossibleChangePasswordForm(); + base::FeatureList::IsEnabled(features::kNewPasswordFormParsing) || + !observed_form.IsPossibleChangePasswordForm(); + + // Wait for the username before filling passwords in case the + // fill-on-account-select-http feature is active and the main frame is + // insecure. + const bool enable_foas_on_http = + base::FeatureList::IsEnabled(features::kFillOnAccountSelectHttp) && + !client.IsMainFrameSecure(); // Proceed to autofill. // Note that we provide the choices but don't actually prefill a value if: @@ -146,9 +152,11 @@ // (2) if it matched using public suffix domain matching, or // (3) it would result in unexpected filling in a form with new password // fields. + // (4) the current main frame origin is insecure and the FOAS on HTTP feature + // is active. bool wait_for_username = client.IsIncognito() || preferred_match->is_public_suffix_match || - !form_good_for_filling; + !form_good_for_filling || enable_foas_on_http; if (wait_for_username) { metrics_recorder->SetManagerAction( @@ -170,12 +178,15 @@ ShowInitialPasswordAccountSuggestions(client, driver, observed_form, best_matches, *preferred_match, wait_for_username); - } else { - // If fill-on-account-select is not enabled, continue with autofilling any - // password forms as traditionally has been done. - Autofill(client, driver, observed_form, best_matches, federated_matches, - *preferred_match, wait_for_username); + return LikelyFormFilling::kShowInitialAccountSuggestions; } + + // If fill-on-account-select is not enabled, continue with autofilling any + // password forms as traditionally has been done. + Autofill(client, driver, observed_form, best_matches, federated_matches, + *preferred_match, wait_for_username); + return wait_for_username ? LikelyFormFilling::kFillOnAccountSelect + : LikelyFormFilling::kFillOnPageLoad; } } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_form_filling.h b/components/password_manager/core/browser/password_form_filling.h index d8ca0282..ac03bd4 100644 --- a/components/password_manager/core/browser/password_form_filling.h +++ b/components/password_manager/core/browser/password_form_filling.h
@@ -20,7 +20,26 @@ class PasswordManagerDriver; class PasswordFormMetricsRecorder; -void SendFillInformationToRenderer( +// Enum detailing the browser process' best belief what kind of credential +// filling is used in the renderer for a given password form. +// +// NOTE: The renderer can still decide not to fill due to reasons that are only +// known to it, thus this enum contains only probable filling kinds. Due to the +// inherent inaccuracy DO NOT record this enum to UMA. +enum class LikelyFormFilling { + // There are no credentials to fill. + kNoFilling, + // The form is rendered with the best matching credential filled in. + kFillOnPageLoad, + // The form requires an active selection of the username before passwords + // are filled. + kFillOnAccountSelect, + // The form is rendered with initial account suggestions, but no credential + // is filled in. + kShowInitialAccountSuggestions, +}; + +LikelyFormFilling SendFillInformationToRenderer( const PasswordManagerClient& client, PasswordManagerDriver* driver, bool is_blacklisted,
diff --git a/components/password_manager/core/browser/password_form_filling_unittest.cc b/components/password_manager/core/browser/password_form_filling_unittest.cc index 0367a62c..72bdf6e 100644 --- a/components/password_manager/core/browser/password_form_filling_unittest.cc +++ b/components/password_manager/core/browser/password_form_filling_unittest.cc
@@ -102,9 +102,10 @@ EXPECT_CALL(driver_, FillPasswordForm(_)).Times(0); EXPECT_CALL(driver_, ShowInitialPasswordAccountSuggestions(_)).Times(0); - SendFillInformationToRenderer( + LikelyFormFilling likely_form_filling = SendFillInformationToRenderer( client_, &driver_, false /* is_blacklisted */, observed_form_, best_matches, federated_matches_, nullptr, metrics_recorder_.get()); + EXPECT_EQ(LikelyFormFilling::kNoFilling, likely_form_filling); } TEST_F(PasswordFormFillingTest, Autofill) { @@ -124,9 +125,10 @@ EXPECT_CALL(driver_, ShowInitialPasswordAccountSuggestions(_)).Times(0); EXPECT_CALL(client_, PasswordWasAutofilled(_, _, _)); - SendFillInformationToRenderer( + LikelyFormFilling likely_form_filling = SendFillInformationToRenderer( client_, &driver_, is_blacklisted, observed_form_, best_matches, federated_matches_, &saved_match_, metrics_recorder_.get()); + EXPECT_EQ(LikelyFormFilling::kFillOnPageLoad, likely_form_filling); // Check that the message to the renderer (i.e. |fill_data|) is filled // correctly. @@ -189,12 +191,13 @@ EXPECT_CALL(driver_, FillPasswordForm(_)).WillOnce(SaveArg<0>(&fill_data)); EXPECT_CALL(client_, PasswordWasAutofilled(_, _, _)); - SendFillInformationToRenderer(client_, &driver_, false, observed_form, - best_matches, federated_matches_, - &saved_match_, metrics_recorder_.get()); + LikelyFormFilling likely_form_filling = SendFillInformationToRenderer( + client_, &driver_, false, observed_form, best_matches, + federated_matches_, &saved_match_, metrics_recorder_.get()); // In all cases, fill on load should not be prevented. If there is no // current-password field, the renderer will not fill anyway. + EXPECT_EQ(LikelyFormFilling::kFillOnPageLoad, likely_form_filling); EXPECT_FALSE(fill_data.wait_for_username); } } @@ -210,10 +213,11 @@ EXPECT_CALL(driver_, ShowInitialPasswordAccountSuggestions(_)).Times(0); EXPECT_CALL(client_, PasswordWasAutofilled(_, _, _)); - SendFillInformationToRenderer(client_, &driver_, false /* is_blacklisted */, - observed_form_, best_matches, - federated_matches_, &psl_saved_match_, - metrics_recorder_.get()); + LikelyFormFilling likely_form_filling = SendFillInformationToRenderer( + client_, &driver_, false /* is_blacklisted */, observed_form_, + best_matches, federated_matches_, &psl_saved_match_, + metrics_recorder_.get()); + EXPECT_EQ(LikelyFormFilling::kFillOnAccountSelect, likely_form_filling); // Check that the message to the renderer (i.e. |fill_data|) is filled // correctly. @@ -226,4 +230,25 @@ EXPECT_EQ(saved_match_.password_value, fill_data.password_field.value); } +TEST_F(PasswordFormFillingTest, FillingOnHttp) { + ASSERT_FALSE(GURL(saved_match_.signon_realm).SchemeIsCryptographic()); + std::map<base::string16, const autofill::PasswordForm*> best_matches; + best_matches.emplace(saved_match_.username_value, &saved_match_); + + for (bool enable_foas_http : {false, true}) { + base::test::ScopedFeatureList features; + enable_foas_http + ? features.InitAndEnableFeature(features::kFillOnAccountSelectHttp) + : features.InitAndDisableFeature(features::kFillOnAccountSelectHttp); + + LikelyFormFilling likely_form_filling = SendFillInformationToRenderer( + client_, &driver_, false /* is_blacklisted */, observed_form_, + best_matches, federated_matches_, &saved_match_, + metrics_recorder_.get()); + EXPECT_EQ(enable_foas_http ? LikelyFormFilling::kFillOnAccountSelect + : LikelyFormFilling::kFillOnPageLoad, + likely_form_filling); + } +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc index f5295abb..2fb7d4c 100644 --- a/components/password_manager/core/browser/password_form_manager.cc +++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -27,7 +27,6 @@ #include "components/password_manager/core/browser/form_fetcher_impl.h" #include "components/password_manager/core/browser/form_saver.h" #include "components/password_manager/core/browser/log_manager.h" -#include "components/password_manager/core/browser/password_form_filling.h" #include "components/password_manager/core/browser/password_manager.h" #include "components/password_manager/core/browser/password_manager_client.h" #include "components/password_manager/core/browser/password_manager_driver.h" @@ -550,10 +549,10 @@ return; if (!driver) return; - SendFillInformationToRenderer(*client_, driver.get(), IsBlacklisted(), - observed_form_, best_matches_, - form_fetcher_->GetFederatedMatches(), - preferred_match_, GetMetricsRecorder()); + likely_form_filling_ = SendFillInformationToRenderer( + *client_, driver.get(), IsBlacklisted(), observed_form_, best_matches_, + form_fetcher_->GetFederatedMatches(), preferred_match_, + GetMetricsRecorder()); } void PasswordFormManager::ProcessLoginPrompt() { @@ -672,12 +671,14 @@ metrics_recorder_->SetUserAction(UserAction::kOverridePassword); } else { // In case |saved_form| is pointing to the same form as - // |preferred_match_|, the user either did not do anything, or - // re-selected the default option. Otherwise, the user purposefully - // chose an alternative. - metrics_recorder_->SetUserAction(saved_form == preferred_match_ - ? UserAction::kNone - : UserAction::kChoose); + // |preferred_match_| and the form was filled on page load, the user + // either did not do anything, or re-selected the default option. + // Otherwise, the user purposefully chose a credential. + metrics_recorder_->SetUserAction( + saved_form == preferred_match_ && + likely_form_filling_ == LikelyFormFilling::kFillOnPageLoad + ? UserAction::kNone + : UserAction::kChoose); } } } else if (!best_matches_.empty() &&
diff --git a/components/password_manager/core/browser/password_form_manager.h b/components/password_manager/core/browser/password_form_manager.h index 6d592bd..ad71b91 100644 --- a/components/password_manager/core/browser/password_form_manager.h +++ b/components/password_manager/core/browser/password_form_manager.h
@@ -22,6 +22,7 @@ #include "components/autofill/core/common/password_form.h" #include "components/autofill/core/common/signatures_util.h" #include "components/password_manager/core/browser/form_fetcher.h" +#include "components/password_manager/core/browser/password_form_filling.h" #include "components/password_manager/core/browser/password_form_manager_for_ui.h" #include "components/password_manager/core/browser/password_form_metrics_recorder.h" #include "components/password_manager/core/browser/password_form_user_action.h" @@ -394,6 +395,9 @@ VotesUploader votes_uploader_; + // Probable filling mechanism used in the renderer for this password form. + LikelyFormFilling likely_form_filling_ = LikelyFormFilling::kNoFilling; + // Takes care of recording metrics and events for this PasswordFormManager. // Make sure to call Init before using |*this|, to ensure it is not null. scoped_refptr<PasswordFormMetricsRecorder> metrics_recorder_;
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc index 236834a..3f3926f 100644 --- a/components/password_manager/core/browser/password_form_manager_unittest.cc +++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -321,6 +321,8 @@ autofill::prefs::kAutofillUploadEncodingSeed, ""); } + MOCK_CONST_METHOD0(IsIncognito, bool()); + PrefService* GetPrefs() const override { return prefs_.get(); } MockPasswordManagerDriver* mock_driver() { return driver_.get(); } @@ -999,7 +1001,7 @@ PasswordForm observed_form_; PasswordForm saved_match_; PasswordForm psl_saved_match_; - TestPasswordManagerClient client_; + NiceMock<TestPasswordManagerClient> client_; std::unique_ptr<PasswordManager> password_manager_; // Define |fake_form_fetcher_| before |form_manager_|, because the former // needs to outlive the latter. @@ -4922,6 +4924,17 @@ form_manager()->ProvisionallySave(preferred_match); EXPECT_EQ(UserAction::kNone, form_manager()->GetMetricsRecorder()->GetUserAction()); + + // Verify that provisionally saving the |preferred_match| with filling on + // account select results in the corresponding user action. Fill on account + // select is simulated by pretending we are in incognito mode. + EXPECT_CALL(*client(), IsIncognito).WillOnce(Return(true)); + fake_form_fetcher()->SetNonFederated( + {&preferred_match, &other_match, &psl_match}, 0); + + form_manager()->ProvisionallySave(preferred_match); + EXPECT_EQ(UserAction::kChoose, + form_manager()->GetMetricsRecorder()->GetUserAction()); } } // namespace password_manager
diff --git a/components/plugins/renderer/webview_plugin.cc b/components/plugins/renderer/webview_plugin.cc index 4c72351..2e78223 100644 --- a/components/plugins/renderer/webview_plugin.cc +++ b/components/plugins/renderer/webview_plugin.cc
@@ -373,14 +373,6 @@ frame_ = nullptr; } -void WebViewPlugin::WebViewHelper::BeginNavigation( - std::unique_ptr<blink::WebNavigationInfo> info) { - // TODO(dgozman): remove this method and effectively disallow - // content-inititated navigations in WebViewPlugin. - frame_->CommitNavigation(blink::WebNavigationParams::CreateFromInfo(*info), - nullptr /* extra_data */); -} - void WebViewPlugin::OnZoomLevelChanged() { if (container_) { web_view()->SetZoomLevel(
diff --git a/components/plugins/renderer/webview_plugin.h b/components/plugins/renderer/webview_plugin.h index 596d5ef..a7f7ae5 100644 --- a/components/plugins/renderer/webview_plugin.h +++ b/components/plugins/renderer/webview_plugin.h
@@ -185,8 +185,6 @@ void BindToFrame(blink::WebNavigationControl* frame) override; void DidClearWindowObject() override; void FrameDetached(DetachType) override; - void BeginNavigation( - std::unique_ptr<blink::WebNavigationInfo> info) override; private: WebViewPlugin* plugin_;
diff --git a/components/policy/resources/policy_templates_fr.xtb b/components/policy/resources/policy_templates_fr.xtb index fda12a4..fe67135a 100644 --- a/components/policy/resources/policy_templates_fr.xtb +++ b/components/policy/resources/policy_templates_fr.xtb
@@ -2660,7 +2660,7 @@ Si une extension ne figure pas dans la liste, ou si la liste n'est pas définie, l'appel vers l'API échoue, et un code d'erreur est renvoyé.</translation> <translation id="7618907117929117943">Rétablissez et conservez la version cible si elle est antérieure à la version de l'OS et qu'il est possible de conserver la configuration de l'appareil (y compris les identifiants réseau) par ce biais, tout en ignorant OOBE après la restauration. Si cela n'est pas possible, n'effectuez pas et n'annulez pas la restauration (car la version cible n'est pas compatible avec la restauration de données ou en raison d'une modification incompatible avec la restauration). Compatible avec la version 70 et les versions ultérieures de <ph name="PRODUCT_OS_NAME" />. Pour les clients plus anciens, cette valeur signifie que la restauration est désactivée.</translation> -<translation id="7620869951155758729">Cette règle définit la configuration utilisée pour générer et validerle code d'accès parental. +<translation id="7620869951155758729">Cette règle définit la configuration utilisée pour générer et valider le code d'accès parental. |current_config| est toujours utilisée pour générer le code d'accès et ne doit être employée pour valider le code d'accès que lorsque ce dernier ne peut pas être validé avec |future_config|. |future_config| est la configuration principale utilisée pour valider le code d'accès.
diff --git a/components/policy/resources/policy_templates_it.xtb b/components/policy/resources/policy_templates_it.xtb index ab1f3fc..84e7744 100644 --- a/components/policy/resources/policy_templates_it.xtb +++ b/components/policy/resources/policy_templates_it.xtb
@@ -2508,7 +2508,7 @@ Questa norma viene applicata solo agli utenti che sono bambini o ragazzi. Quando questa norma è impostata, il codice di accesso genitori può essere verificato sul dispositivo dell'utente bambino o ragazzo. - Quando questa norma è non è impostata, non è possibile verificare il codice di accesso genitori sul dispositivo dell'utente bambino o ragazzo.</translation> + Quando questa norma non è impostata, non è possibile verificare il codice di accesso genitori sul dispositivo dell'utente bambino o ragazzo.</translation> <translation id="7625444193696794922">Consente di specificare il canale di rilascio su cui deve essere bloccato questo dispositivo.</translation> <translation id="7632724434767231364">Nome della libreria GSSAPI</translation> <translation id="7635471475589566552">Consente di configurare in <ph name="PRODUCT_NAME" /> le impostazioni della lingua e di impedirne la modifica agli utenti. Se attivi questa impostazione, <ph name="PRODUCT_NAME" /> utilizzerà le impostazioni della lingua specificate. Se la lingua configurata non è supportata, verrà utilizzata la lingua "en-US". Se questa impostazione viene disattivata o non viene impostata, <ph name="PRODUCT_NAME" /> utilizzerà la lingua preferita specificata dall'utente (se configurata), quella del sistema o la lingua di fallback "en-US".</translation>
diff --git a/components/policy/resources/policy_templates_ja.xtb b/components/policy/resources/policy_templates_ja.xtb index b473680b..49df20a 100644 --- a/components/policy/resources/policy_templates_ja.xtb +++ b/components/policy/resources/policy_templates_ja.xtb
@@ -2556,7 +2556,7 @@ <translation id="7620869951155758729">このポリシーでは、保護者のアクセスコードの生成と確認に使用する設定を指定します。 |current_config| は常にアクセスコードの生成に使用され、|future_config| でアクセスコードを確認できなかった場合に限り確認に使用されます。 |future_config| はアクセスコードの確認に使用されるメインの設定です。|old_configs| は、|future_config| と |current_config| でアクセスコードを確認できなかった場合に限り確認に使用されます。 -このポリシーは、アクセスコード設定を段階的に切り替える場合に使用することを想定しています。新しい設定は常に |future_config| に入力され、同時に既存の値は |current_config| に移動されます。|current_config| の以前の値は |old_configs| に移動され、切り替えが完了した後に削除されます。このポリシーは子どものユーザーにのみ適用されます。このポリシーが設定されている場合、子どものユーザーの端末で保護者のアクセスコードを確認できます。このポリシーが設定されていない場合、子どものユーザーの端末で保護者のアクセスコードを確認できません。</translation> +このポリシーは、アクセスコード設定を段階的に切り替える場合に使用することを想定しています。新しい設定は常に |future_config| に入力され、同時に既存の値は |current_config| に移動されます。|current_config| の以前の値は |old_configs| に移動され、切り替えが完了した後に削除されます。このポリシーは子どものユーザーにのみ適用されます。このポリシーが設定されている場合、子どものユーザーのデバイスで保護者のアクセスコードを確認できます。このポリシーが設定されていない場合、子どものユーザーのデバイスで保護者のアクセスコードを確認できません。</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>
diff --git a/components/policy/resources/policy_templates_pl.xtb b/components/policy/resources/policy_templates_pl.xtb index cfd04e29f..a520d49 100644 --- a/components/policy/resources/policy_templates_pl.xtb +++ b/components/policy/resources/policy_templates_pl.xtb
@@ -2557,7 +2557,7 @@ Konfiguracji |old_configs| należy używać do weryfikacji kodu dostępu tylko wtedy, gdy nie można tego zrobić przy użyciu konfiguracji |future_config| ani |current_config|. Przeznaczeniem tej zasady jest stopniowa rotacja konfiguracji kodu dostępu. Nowa konfiguracja jest zawsze zapisywana w elemencie |future_config|, a istniejąca wartość - jest przenoszona do elementu |current_config|. Wcześniejsze wartości zapisane w konfiguracji |current_config| są przenoszone konfiguracji |old_configs| i usuwane po zakończeniu cyklu rotacji. + jest przenoszona do elementu |current_config|. Wcześniejsze wartości zapisane w konfiguracji |current_config| są przenoszone do konfiguracji |old_configs| i usuwane po zakończeniu cyklu rotacji. Ta zasada dotyczy tylko dzieci. Jeśli ta zasada jest ustawiona, kod dostępu rodzica można zweryfikować na urządzeniu dziecka.
diff --git a/components/policy/resources/policy_templates_sk.xtb b/components/policy/resources/policy_templates_sk.xtb index 68726eb..c01ecf21 100644 --- a/components/policy/resources/policy_templates_sk.xtb +++ b/components/policy/resources/policy_templates_sk.xtb
@@ -2633,7 +2633,7 @@ Očakávaným spôsobom používania týchto pravidiel je postupné striedanie konfigurácie prístupového kódu. Nová konfigurácia sa vždy vloží do konfigurácie |future_config| a zároveň sa existujúca hodnota presunie do konfigurácie |current_config|. Predchádzajúce hodnoty konfigurácie |current_config| sa presunú do konfigurácie |old_configs| a následne odstránia po dokončení cyklu striedania. Tieto pravidlá sa používajú iba pre detských používateľov. - Ak je toto pravidlo nastavené, prístupový kód rodiča je možné overiť na zariadení detského používateľa. + Ak je toto pravidlo nastavené, prístupový kód rodiča je možné overiť v zariadení detského používateľa. Ak toto pravidlo nie je nastavené, prístupový kód rodiča nie je možné overiť v zariadení detského používateľa.</translation> <translation id="7625444193696794922">Určuje, aký kanál verzie by mal byť v zariadení uzamknutý.</translation> <translation id="7632724434767231364">Názov knižnice GSSAPI</translation>
diff --git a/components/policy/resources/policy_templates_sw.xtb b/components/policy/resources/policy_templates_sw.xtb index beaee35..4e4117b9 100644 --- a/components/policy/resources/policy_templates_sw.xtb +++ b/components/policy/resources/policy_templates_sw.xtb
@@ -2609,11 +2609,10 @@ <translation id="7620869951155758729">Sera hii inaeleza mipangilio inayotumika kuunda na kuthibitisha Msimbo wa Kufikia wa Mzazi. |current_config| hutumika kila mara kuunda msimbo wa kufikia na inapaswa kutumika kuthibitisha msimbo wa kufikia iwapo tu hauwezi kuthibitishwa na |future_config|. - |future_config| ni mpangilio wa msingi unaotumiwa kuthibitisha msimbo wa kufikia. +|future_config| ni mpangilio wa msingi unaotumiwa kuthibitisha msimbo wa kufikia. |old_configs| inapaswa kutumika kuthibitisha msimbo wa kufikia iwapo tu hauwezi kuthibitishwa na |future_config| wala |current_config|. - Njia inayotarajiwa ya kutumia sera hii ni kuzungusha kwa hatua mpangilio wa msimbo wa kufikia. Mipangilio mipya huwekwa kwenye |future_config| kila mara na wakati huo huo - thamani iliyopo huhamishiwa kwenye |current_config|. Thamani za awali za |current_config| zitahamishiwa kwenye |old_configs| na kuondolewa bada ya mzunguko kukamilika. + Njia inayotarajiwa ya kutumia sera hii ni kuzungusha kwa hatua mpangilio wa msimbo wa kufikia. Mipangilio mipya huwekwa kwenye |future_config| kila mara na wakati huo huo thamani iliyopo huhamishiwa kwenye |current_config|. Thamani za awali za |current_config| zitahamishiwa kwenye |old_configs| na kuondolewa bada ya mzunguko kukamilika. Sera hii inatumika kwa mtumiaji mtoto pekee. Sera hii inapowekwa, mipangilio ya Msimbo wa kufikia wa Mzazi inaweza kuthibitishwa kwenye kifaa kinachotumiwa na mtoto.
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc index 60537c4..4110bc8 100644 --- a/components/printing/renderer/print_render_frame_helper.cc +++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -678,12 +678,6 @@ frame_->Close(); frame_ = nullptr; } - void BeginNavigation( - std::unique_ptr<blink::WebNavigationInfo> info) override { - frame_->CommitNavigation( - blink::WebNavigationParams::CreateFromInfo(*info), - nullptr /* extra_data */); - } private: blink::WebNavigationControl* frame_ = nullptr; @@ -792,7 +786,6 @@ const blink::WebFrameOwnerProperties& frame_owner_properties, blink::FrameOwnerElementType owner_type) override; void FrameDetached(DetachType detach_type) override; - void BeginNavigation(std::unique_ptr<blink::WebNavigationInfo> info) override; std::unique_ptr<blink::WebURLLoaderFactory> CreateURLLoaderFactory() override; void CallOnReady(); @@ -984,15 +977,6 @@ frame_.Reset(nullptr); } -void PrepareFrameAndViewForPrint::BeginNavigation( - std::unique_ptr<blink::WebNavigationInfo> info) { - // TODO(dgozman): We disable javascript through WebPreferences, so perhaps - // we want to disallow any navigations here by just removing this method? - navigation_control_->CommitNavigation( - blink::WebNavigationParams::CreateFromInfo(*info), - nullptr /* extra_data */); -} - std::unique_ptr<blink::WebURLLoaderFactory> PrepareFrameAndViewForPrint::CreateURLLoaderFactory() { return blink::Platform::Current()->CreateDefaultURLLoaderFactory();
diff --git a/components/renderer_context_menu/render_view_context_menu_base.h b/components/renderer_context_menu/render_view_context_menu_base.h index 0204287b..09ae71d5 100644 --- a/components/renderer_context_menu/render_view_context_menu_base.h +++ b/components/renderer_context_menu/render_view_context_menu_base.h
@@ -115,8 +115,8 @@ friend class RenderViewContextMenuTest; friend class RenderViewContextMenuPrefsTest; - void set_content_type(ContextMenuContentType* content_type) { - content_type_.reset(content_type); + void set_content_type(std::unique_ptr<ContextMenuContentType> content_type) { + content_type_ = std::move(content_type); } void set_toolkit_delegate(std::unique_ptr<ToolkitDelegate> delegate) {
diff --git a/components/search_provider_logos/logo_service_impl_unittest.cc b/components/search_provider_logos/logo_service_impl_unittest.cc index 2cf40aa..66d559a9 100644 --- a/components/search_provider_logos/logo_service_impl_unittest.cc +++ b/components/search_provider_logos/logo_service_impl_unittest.cc
@@ -36,12 +36,6 @@ #include "components/search_provider_logos/google_logo_api.h" #include "components/search_provider_logos/logo_cache.h" #include "components/search_provider_logos/logo_observer.h" -#include "components/signin/core/browser/account_tracker_service.h" -#include "components/signin/core/browser/fake_gaia_cookie_manager_service.h" -#include "components/signin/core/browser/fake_profile_oauth2_token_service.h" -#include "components/signin/core/browser/fake_signin_manager.h" -#include "components/signin/core/browser/test_signin_client.h" -#include "components/sync_preferences/testing_pref_service_syncable.h" #include "net/base/url_util.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" @@ -289,59 +283,24 @@ // signing in/out. class SigninHelper { public: - explicit SigninHelper(base::test::ScopedTaskEnvironment* task_environment) - : task_environment_(task_environment), - signin_client_(&pref_service_), - token_service_(&pref_service_), - cookie_service_(&token_service_, - &signin_client_, - &test_url_loader_factory_), -#if defined(OS_CHROMEOS) - signin_manager_(&signin_client_, - &token_service_, - &account_tracker_service_), -#else - signin_manager_(&signin_client_, - &token_service_, - &account_tracker_service_, - &cookie_service_), -#endif - identity_test_env_(&account_tracker_service_, - &token_service_, - &signin_manager_, - &cookie_service_) { - // GaiaCookieManagerService calls static methods of AccountTrackerService - // which access prefs. - AccountTrackerService::RegisterPrefs(pref_service_.registry()); - } + explicit SigninHelper() : identity_test_env_(&test_url_loader_factory_) {} identity::IdentityManager* identity_manager() { return identity_test_env_.identity_manager(); } void SignIn() { - cookie_service_.SetListAccountsResponseOneAccount("user@gmail.com", - "gaia_id"); - cookie_service_.TriggerListAccounts(); - task_environment_->RunUntilIdle(); + std::string email("user@gmail.com"); + identity_test_env_.SetCookieAccounts( + {{email, identity::GetTestGaiaIdForEmail(email)}}); } void SignOut() { - cookie_service_.SetListAccountsResponseNoAccounts(); - cookie_service_.TriggerListAccounts(); - task_environment_->RunUntilIdle(); + identity_test_env_.SetCookieAccounts({}); } private: - base::test::ScopedTaskEnvironment* task_environment_; - - TestingPrefServiceSyncable pref_service_; - TestSigninClient signin_client_; - FakeProfileOAuth2TokenService token_service_; - AccountTrackerService account_tracker_service_; network::TestURLLoaderFactory test_url_loader_factory_; - FakeGaiaCookieManagerService cookie_service_; - SigninManagerForTest signin_manager_; identity::IdentityTestEnvironment identity_test_env_; }; @@ -353,7 +312,6 @@ shared_factory_( base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &test_url_loader_factory_)), - signin_helper_(&task_environment_), use_gray_background_(false) { test_url_loader_factory_.SetInterceptor(base::BindRepeating( &LogoServiceImplTest::CapturingInterceptor, base::Unretained(this)));
diff --git a/components/signin/core/browser/account_reconcilor_unittest.cc b/components/signin/core/browser/account_reconcilor_unittest.cc index d42fbea..48d102c 100644 --- a/components/signin/core/browser/account_reconcilor_unittest.cc +++ b/components/signin/core/browser/account_reconcilor_unittest.cc
@@ -353,7 +353,7 @@ &test_signin_client_, &test_url_loader_factory_), #if defined(OS_CHROMEOS) - signin_manager_(&test_signin_client_, &token_service_, &account_tracker_), + signin_manager_(&test_signin_client_, &account_tracker_), #else signin_manager_(&test_signin_client_, &token_service_,
diff --git a/components/signin/core/browser/fake_signin_manager.cc b/components/signin/core/browser/fake_signin_manager.cc index 5a19dca..8013a5e 100644 --- a/components/signin/core/browser/fake_signin_manager.cc +++ b/components/signin/core/browser/fake_signin_manager.cc
@@ -14,11 +14,9 @@ FakeSigninManagerBase::FakeSigninManagerBase( SigninClient* client, - ProfileOAuth2TokenService* token_service, AccountTrackerService* account_tracker_service, SigninErrorController* signin_error_controller) : SigninManagerBase(client, - token_service, account_tracker_service, signin_error_controller) {}
diff --git a/components/signin/core/browser/fake_signin_manager.h b/components/signin/core/browser/fake_signin_manager.h index 1196edd..33a2af3 100644 --- a/components/signin/core/browser/fake_signin_manager.h +++ b/components/signin/core/browser/fake_signin_manager.h
@@ -19,7 +19,6 @@ public: FakeSigninManagerBase( SigninClient* client, - ProfileOAuth2TokenService* token_service, AccountTrackerService* account_tracker_service, SigninErrorController* signin_error_controller = nullptr); ~FakeSigninManagerBase() override;
diff --git a/components/signin/core/browser/signin_manager.cc b/components/signin/core/browser/signin_manager.cc index 0602af4..f3e9f1b1 100644 --- a/components/signin/core/browser/signin_manager.cc +++ b/components/signin/core/browser/signin_manager.cc
@@ -33,10 +33,11 @@ SigninErrorController* signin_error_controller, signin::AccountConsistencyMethod account_consistency) : SigninManagerBase(client, - token_service, account_tracker_service, signin_error_controller), type_(SIGNIN_TYPE_NONE), + client_(client), + token_service_(token_service), cookie_manager_service_(cookie_manager_service), account_consistency_(account_consistency), signin_manager_signed_in_(false), @@ -125,7 +126,7 @@ possibly_invalid_email_ = source.possibly_invalid_email_; temp_refresh_token_ = source.temp_refresh_token_; password_ = source.password_; - source.signin_client()->AfterCredentialsCopied(); + source.client_->AfterCredentialsCopied(); } void SigninManager::ClearTransientSigninData() { @@ -174,7 +175,7 @@ signin_metrics::ProfileSignout signout_source_metric, signin_metrics::SignoutDelete signout_delete_metric, RemoveAccountsOption remove_option) { - signin_client()->PreSignOut( + client_->PreSignOut( base::BindOnce(&SigninManager::OnSignoutDecisionReached, base::Unretained(this), signout_source_metric, signout_delete_metric, remove_option), @@ -217,14 +218,13 @@ AccountInfo account_info = GetAuthenticatedAccountInfo(); const std::string account_id = GetAuthenticatedAccountId(); const std::string username = account_info.email; - const base::Time signin_time = - base::Time::FromDeltaSinceWindowsEpoch(base::TimeDelta::FromMicroseconds( - signin_client()->GetPrefs()->GetInt64(prefs::kSignedInTime))); + const base::Time signin_time = base::Time::FromInternalValue( + client_->GetPrefs()->GetInt64(prefs::kSignedInTime)); ClearAuthenticatedAccountId(); - signin_client()->GetPrefs()->ClearPref(prefs::kGoogleServicesHostedDomain); - signin_client()->GetPrefs()->ClearPref(prefs::kGoogleServicesAccountId); - signin_client()->GetPrefs()->ClearPref(prefs::kGoogleServicesUserAccountId); - signin_client()->GetPrefs()->ClearPref(prefs::kSignedInTime); + client_->GetPrefs()->ClearPref(prefs::kGoogleServicesHostedDomain); + client_->GetPrefs()->ClearPref(prefs::kGoogleServicesAccountId); + client_->GetPrefs()->ClearPref(prefs::kGoogleServicesUserAccountId); + client_->GetPrefs()->ClearPref(prefs::kSignedInTime); // Determine the duration the user was logged in and log that to UMA. if (!signin_time.is_null()) { @@ -240,13 +240,13 @@ case RemoveAccountsOption::kRemoveAllAccounts: VLOG(0) << "Revoking all refresh tokens on server. Reason: sign out, " << "IsSigninAllowed: " << IsSigninAllowed(); - token_service()->RevokeAllCredentials( + token_service_->RevokeAllCredentials( signin_metrics::SourceForRefreshTokenOperation:: kSigninManager_ClearPrimaryAccount); break; case RemoveAccountsOption::kRemoveAuthenticatedAccountIfInError: - if (token_service()->RefreshTokenHasError(account_id)) - token_service()->RevokeCredentials( + if (token_service_->RefreshTokenHasError(account_id)) + token_service_->RevokeCredentials( account_id, signin_metrics::SourceForRefreshTokenOperation:: kSigninManager_ClearPrimaryAccount); break; @@ -258,8 +258,9 @@ FireGoogleSignedOut(account_info); } -void SigninManager::FinalizeInitBeforeLoadingRefreshTokens( - PrefService* local_state) { +void SigninManager::Initialize(PrefService* local_state) { + SigninManagerBase::Initialize(local_state); + // local_state can be null during unit tests. if (local_state) { local_state_pref_registrar_.Init(local_state); @@ -268,12 +269,12 @@ base::Bind(&SigninManager::OnGoogleServicesUsernamePatternChanged, weak_pointer_factory_.GetWeakPtr())); } - signin_allowed_.Init(prefs::kSigninAllowed, signin_client()->GetPrefs(), + signin_allowed_.Init(prefs::kSigninAllowed, client_->GetPrefs(), base::Bind(&SigninManager::OnSigninAllowedPrefChanged, base::Unretained(this))); std::string account_id = - signin_client()->GetPrefs()->GetString(prefs::kGoogleServicesAccountId); + client_->GetPrefs()->GetString(prefs::kGoogleServicesAccountId); std::string user = account_id.empty() ? std::string() : account_tracker_service()->GetAccountInfo(account_id).email; if (!account_id.empty() && (!IsAllowedUsername(user) || !IsSigninAllowed())) { @@ -302,11 +303,12 @@ // It is important to only load credentials after starting to observe the // token service. - token_service()->AddObserver(this); + token_service_->AddObserver(this); + token_service_->LoadCredentials(GetAuthenticatedAccountId()); } void SigninManager::Shutdown() { - token_service()->RemoveObserver(this); + token_service_->RemoveObserver(this); account_tracker_service()->RemoveObserver(this); local_state_pref_registrar_.RemoveAll(); SigninManagerBase::Shutdown(); @@ -387,7 +389,7 @@ if (!temp_refresh_token_.empty()) { std::string account_id = GetAuthenticatedAccountId(); - token_service()->UpdateCredentials( + token_service_->UpdateCredentials( account_id, temp_refresh_token_, signin_metrics::SourceForRefreshTokenOperation:: kSigninManager_LegacyPreDiceSigninFlow); @@ -410,9 +412,8 @@ void SigninManager::OnSignedIn() { bool reauth_in_progress = IsAuthenticated(); - signin_client()->GetPrefs()->SetInt64( - prefs::kSignedInTime, - base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds()); + client_->GetPrefs()->SetInt64(prefs::kSignedInTime, + base::Time::Now().ToInternalValue()); SetAuthenticatedAccountInfo(possibly_invalid_gaia_id_, possibly_invalid_email_); @@ -426,8 +427,8 @@ if (!reauth_in_progress) FireGoogleSigninSucceeded(); - signin_metrics::LogSigninProfile(signin_client()->IsFirstRun(), - signin_client()->GetInstallDate()); + signin_metrics::LogSigninProfile(client_->IsFirstRun(), + client_->GetInstallDate()); PostSignedIn(); } @@ -450,8 +451,8 @@ if (!signin_manager_signed_in_ || !user_info_fetched_by_account_tracker_) return; - signin_client()->PostSignedIn(GetAuthenticatedAccountId(), - GetAuthenticatedAccountInfo().email, password_); + client_->PostSignedIn(GetAuthenticatedAccountId(), + GetAuthenticatedAccountInfo().email, password_); password_.clear(); } @@ -469,7 +470,7 @@ } void SigninManager::OnRefreshTokensLoaded() { - token_service()->RemoveObserver(this); + token_service_->RemoveObserver(this); if (account_tracker_service()->GetMigrationState() == AccountTrackerService::MIGRATION_IN_PROGRESS) { @@ -477,12 +478,12 @@ } // Remove account information from the account tracker service if needed. - if (token_service()->HasLoadCredentialsFinishedWithNoErrors()) { + if (token_service_->HasLoadCredentialsFinishedWithNoErrors()) { std::vector<AccountInfo> accounts_in_tracker_service = account_tracker_service()->GetAccounts(); for (const auto& account : accounts_in_tracker_service) { if (GetAuthenticatedAccountId() != account.account_id && - !token_service()->RefreshTokenIsAvailable(account.account_id)) { + !token_service_->RefreshTokenIsAvailable(account.account_id)) { DVLOG(0) << "Removed account from account tracker service: " << account.account_id; account_tracker_service()->RemoveAccount(account.account_id);
diff --git a/components/signin/core/browser/signin_manager.h b/components/signin/core/browser/signin_manager.h index d91d8b1..83682f78 100644 --- a/components/signin/core/browser/signin_manager.h +++ b/components/signin/core/browser/signin_manager.h
@@ -48,6 +48,8 @@ class GaiaCookieManagerService; class GoogleServiceAuthError; class PrefService; +class ProfileOAuth2TokenService; +class SigninClient; class SigninErrorController; namespace identity { @@ -141,9 +143,7 @@ // On platforms where SigninManager is responsible for dealing with // invalid username policy updates, we need to check this during // initialization and sign the user out. - void FinalizeInitBeforeLoadingRefreshTokens( - PrefService* local_state) override; - + void Initialize(PrefService* local_state) override; void Shutdown() override; // If applicable, merge the signed in account into the cookie jar. @@ -268,6 +268,14 @@ // token service so that it does not need to mint new ones. std::string temp_refresh_token_; + // The SigninClient object associated with this object. Must outlive this + // object. + SigninClient* client_; + + // The ProfileOAuth2TokenService instance associated with this object. Must + // outlive this object. + ProfileOAuth2TokenService* token_service_; + // Object used to use the token to push a GAIA cookie into the cookie jar. GaiaCookieManagerService* cookie_manager_service_;
diff --git a/components/signin/core/browser/signin_manager_base.cc b/components/signin/core/browser/signin_manager_base.cc index 6dde0dd..85fb881 100644 --- a/components/signin/core/browser/signin_manager_base.cc +++ b/components/signin/core/browser/signin_manager_base.cc
@@ -16,7 +16,6 @@ #include "components/prefs/pref_service.h" #include "components/signin/core/browser/account_info.h" #include "components/signin/core/browser/account_tracker_service.h" -#include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_client.h" #include "components/signin/core/browser/signin_error_controller.h" #include "components/signin/core/browser/signin_pref_names.h" @@ -27,11 +26,9 @@ SigninManagerBase::SigninManagerBase( SigninClient* client, - ProfileOAuth2TokenService* token_service, AccountTrackerService* account_tracker_service, SigninErrorController* signin_error_controller) : client_(client), - token_service_(token_service), account_tracker_service_(account_tracker_service), signin_error_controller_(signin_error_controller), initialized_(false), @@ -151,13 +148,8 @@ } SetAuthenticatedAccountId(account_id); } - FinalizeInitBeforeLoadingRefreshTokens(local_state); - token_service()->LoadCredentials(GetAuthenticatedAccountId()); } -void SigninManagerBase::FinalizeInitBeforeLoadingRefreshTokens( - PrefService* local_state) {} - bool SigninManagerBase::IsInitialized() const { return initialized_; } bool SigninManagerBase::IsSigninAllowed() const {
diff --git a/components/signin/core/browser/signin_manager_base.h b/components/signin/core/browser/signin_manager_base.h index 6dc0895..89365f6a 100644 --- a/components/signin/core/browser/signin_manager_base.h +++ b/components/signin/core/browser/signin_manager_base.h
@@ -41,7 +41,6 @@ class AccountTrackerService; class PrefRegistrySimple; class PrefService; -class ProfileOAuth2TokenService; class SigninClient; class SigninErrorController; @@ -96,7 +95,6 @@ private: #endif SigninManagerBase(SigninClient* client, - ProfileOAuth2TokenService* token_service, AccountTrackerService* account_tracker_service, SigninErrorController* signin_error_controller); #if !defined(OS_CHROMEOS) @@ -112,7 +110,7 @@ static void RegisterPrefs(PrefRegistrySimple* registry); // If user was signed in, load tokens from DB if available. - void Initialize(PrefService* local_state); + virtual void Initialize(PrefService* local_state); bool IsInitialized() const; // Returns true if a signin to Chrome is allowed (by policy or pref). @@ -159,8 +157,6 @@ // Gives access to the SigninClient instance associated with this instance. SigninClient* signin_client() const { return client_; } - ProfileOAuth2TokenService* token_service() const { return token_service_; } - // Adds a callback that will be called when this instance is shut down.Not // intended for general usage, but rather for usage only by the Identity // Service implementation during the time period of conversion of Chrome to @@ -175,10 +171,6 @@ return account_tracker_service_; } - // Invoked at the end of |Initialize| before the refresh token for the primary - // account is loaded. - virtual void FinalizeInitBeforeLoadingRefreshTokens(PrefService* local_state); - // Sets the authenticated user's account id. // If the user is already authenticated with the same account id, then this // method is a no-op. @@ -208,11 +200,6 @@ friend class SigninManager; SigninClient* client_; - - // The ProfileOAuth2TokenService instance associated with this object. Must - // outlive this object. - ProfileOAuth2TokenService* token_service_; - AccountTrackerService* account_tracker_service_; SigninErrorController* signin_error_controller_; bool initialized_;
diff --git a/components/signin/core/browser/signin_tracker_unittest.cc b/components/signin/core/browser/signin_tracker_unittest.cc index e897771..87a6d5c8 100644 --- a/components/signin/core/browser/signin_tracker_unittest.cc +++ b/components/signin/core/browser/signin_tracker_unittest.cc
@@ -56,9 +56,7 @@ &signin_client_, &test_url_loader_factory_), #if defined(OS_CHROMEOS) - fake_signin_manager_(&signin_client_, - &fake_oauth2_token_service_, - &account_tracker_) { + fake_signin_manager_(&signin_client_, &account_tracker_) { #else fake_signin_manager_(&signin_client_, &fake_oauth2_token_service_,
diff --git a/components/strings/components_strings_am.xtb b/components/strings/components_strings_am.xtb index 2c7757a8f7..808bab9 100644 --- a/components/strings/components_strings_am.xtb +++ b/components/strings/components_strings_am.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">የማውጫ የኤፒአይ መታወቂያ፦</translation> <translation id="2597378329261239068">ይህ ሰነድ በይለፍ ቃል የተጠበቀ ነው። እባክዎ የይለፍ ቃል ያስገቡ።</translation> <translation id="2609632851001447353">ልዩነቶች</translation> -<translation id="262424810616849754">{COUNT,plural, =0{ምንም}=1{1 መተግበሪያ ($1)}=2{2 መተግበሪያዎች ($1፣ $2)}one{# መተግበሪያዎች ($1፣ $2፣ $3)}other{# መተግበሪያዎች ($1፣ $2፣ $3)}}</translation> <translation id="2625385379895617796">የእርስዎ ሰዓት ገና የወደፊት ነው</translation> <translation id="2634124572758952069">የ<ph name="HOST_NAME" /> አገልጋይ አይፒ አድራሻ ሊገኝ አልቻለም።</translation> <translation id="2639739919103226564">ሁኔታ፦</translation>
diff --git a/components/strings/components_strings_ar.xtb b/components/strings/components_strings_ar.xtb index 762fd57..2276a3b 100644 --- a/components/strings/components_strings_ar.xtb +++ b/components/strings/components_strings_ar.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">رقم تعريف واجهة برمجة التطبيقات الدليل:</translation> <translation id="2597378329261239068">هذا المستند محمي بكلمة المرور. يُرجى إدخال كلمة مرور.</translation> <translation id="2609632851001447353">الاختلافات</translation> -<translation id="262424810616849754">{COUNT,plural, =0{بدون}=1{تطبيق واحد ($1)}=2{تطبيقان (2) ($1، $2)}few{# تطبيقات ($1، $2، $3)}many{# تطبيقًا ($1، $2، $3)}other{# تطبيق ($1، $2، $3)}}</translation> <translation id="2625385379895617796">توقيت ساعتك متقدم عن الوقت الحالي</translation> <translation id="2634124572758952069">تعذّر العثور على عنوان IP لخادم <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">الحالة:</translation>
diff --git a/components/strings/components_strings_bg.xtb b/components/strings/components_strings_bg.xtb index 1676e21..ccd686c2 100644 --- a/components/strings/components_strings_bg.xtb +++ b/components/strings/components_strings_bg.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">ID на API за директории:</translation> <translation id="2597378329261239068">Този документ е защитен с парола. Моля, въведете я.</translation> <translation id="2609632851001447353">Вариации</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Няма}=1{1 приложение ($1)}=2{2 приложения ($1, $2)}other{# приложения ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Часовникът ви е напред</translation> <translation id="2634124572758952069">IP адресът на сървъра на <ph name="HOST_NAME" /> не можа да бъде намерен.</translation> <translation id="2639739919103226564">Състояние:</translation>
diff --git a/components/strings/components_strings_bn.xtb b/components/strings/components_strings_bn.xtb index 70f3345..1436d71 100644 --- a/components/strings/components_strings_bn.xtb +++ b/components/strings/components_strings_bn.xtb
@@ -256,7 +256,6 @@ <translation id="2587841377698384444">ডিরেক্টরি API আইডি:</translation> <translation id="2597378329261239068">এই দস্তাবেজটি পাসওয়ার্ড সুরক্ষিত৷ দয়া করে একটি পাসওয়ার্ড লিখুন৷</translation> <translation id="2609632851001447353">বৈচিত্রতা</translation> -<translation id="262424810616849754">{COUNT,plural, =0{কিছুই নয়}=1{১টি অ্যাপ ($১)}=2{২টি অ্যাপ ($১, $২)}one{#টি অ্যাপ ($১, $২, $৩)}other{#টি অ্যাপ ($১, $২, $৩)}}</translation> <translation id="2625385379895617796">আপনার ঘড়ির সময় অনেকটা এগিয়ে</translation> <translation id="2634124572758952069"><ph name="HOST_NAME" />এর সার্ভার IP অ্যাড্রেস পাওয়া যায়নি।</translation> <translation id="2639739919103226564">স্থিতি: </translation>
diff --git a/components/strings/components_strings_ca.xtb b/components/strings/components_strings_ca.xtb index ccdcbdf..eaccbe2 100644 --- a/components/strings/components_strings_ca.xtb +++ b/components/strings/components_strings_ca.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Identificador de l'API de directoris:</translation> <translation id="2597378329261239068">Aquest document està protegit mitjançant contrasenya. Introduïu una contrasenya.</translation> <translation id="2609632851001447353">Variacions</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Cap}=1{1 aplicació ($1)}=2{2 aplicacions ($1, $2)}other{# aplicacions ($1, $2, $3)}}</translation> <translation id="2625385379895617796">El rellotge està avançat</translation> <translation id="2634124572758952069">No s'ha trobat l'adreça IP del servidor de l'amfitrió <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">Estat:</translation>
diff --git a/components/strings/components_strings_cs.xtb b/components/strings/components_strings_cs.xtb index 0585405..63409f9 100644 --- a/components/strings/components_strings_cs.xtb +++ b/components/strings/components_strings_cs.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">ID rozhraní Directory API:</translation> <translation id="2597378329261239068">Tento dokument je chráněn heslem. Zadejte prosím heslo.</translation> <translation id="2609632851001447353">Varianty</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Žádné}=1{1 aplikace ($1)}=2{2 aplikace ($1, $2)}few{# aplikace ($1, $2 $3)}many{# aplikace ($1, $2 $3)}other{# aplikací ($1, $2 $3)}}</translation> <translation id="2625385379895617796">Vaše hodiny jdou napřed</translation> <translation id="2634124572758952069">IP adresa serveru <ph name="HOST_NAME" /> nebyla nalezena.</translation> <translation id="2639739919103226564">Stav:</translation>
diff --git a/components/strings/components_strings_da.xtb b/components/strings/components_strings_da.xtb index 109e936..98a50eb 100644 --- a/components/strings/components_strings_da.xtb +++ b/components/strings/components_strings_da.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Id for Directory API:</translation> <translation id="2597378329261239068">Dette dokument er adgangskodebeskyttet. Angiv en adgangskode.</translation> <translation id="2609632851001447353">Varianter</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Ingen}=1{1 app ($1)}=2{2 apps ($1, $2)}one{# app ($1, $2, $3)}other{# apps ($1, $2 $3)}}</translation> <translation id="2625385379895617796">Dit ur er foran</translation> <translation id="2634124572758952069">IP-adressen på serveren for <ph name="HOST_NAME" /> kunne ikke findes.</translation> <translation id="2639739919103226564">Status:</translation>
diff --git a/components/strings/components_strings_de.xtb b/components/strings/components_strings_de.xtb index 7bf97fc..009fb51 100644 --- a/components/strings/components_strings_de.xtb +++ b/components/strings/components_strings_de.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Directory API-ID:</translation> <translation id="2597378329261239068">Dieses Dokument ist passwortgeschützt. Geben Sie ein Passwort ein.</translation> <translation id="2609632851001447353">Varianten</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Keine}=1{1 App ($1)}=2{2 Apps ($1, $2)}other{# Apps ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Ihre Uhr geht vor.</translation> <translation id="2634124572758952069">Die Server-IP-Adresse von <ph name="HOST_NAME" /> wurde nicht gefunden.</translation> <translation id="2639739919103226564">Status:</translation>
diff --git a/components/strings/components_strings_el.xtb b/components/strings/components_strings_el.xtb index 7eb43bb3..f50634d 100644 --- a/components/strings/components_strings_el.xtb +++ b/components/strings/components_strings_el.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Αναγνωριστικό API καταλόγου:</translation> <translation id="2597378329261239068">Αυτό το έγγραφο προστατεύεται με κωδικό πρόσβασης. Πληκτρολογήστε έναν κωδικό πρόσβασης.</translation> <translation id="2609632851001447353">Παραλλαγές</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Καμία}=1{1 εφαρμογή ($1)}=2{2 εφαρμογές ($1, $2)}other{# εφαρμογές ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Το ρολόι σας πάει μπροστά</translation> <translation id="2634124572758952069">Δεν ήταν δυνατή η εύρεση της διεύθυνσης IP διακομιστή του κεντρικού υπολογιστή <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">Κατάσταση:</translation>
diff --git a/components/strings/components_strings_en-GB.xtb b/components/strings/components_strings_en-GB.xtb index 606f2e3..0687310 100644 --- a/components/strings/components_strings_en-GB.xtb +++ b/components/strings/components_strings_en-GB.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Directory API ID:</translation> <translation id="2597378329261239068">This document is password-protected. Please enter a password.</translation> <translation id="2609632851001447353">Variations</translation> -<translation id="262424810616849754">{COUNT,plural, =0{None}=1{1 app ($1)}=2{2 apps ($1, $2)}other{# apps ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Your clock is ahead</translation> <translation id="2634124572758952069"><ph name="HOST_NAME" />’s server IP address could not be found.</translation> <translation id="2639739919103226564">Status:</translation>
diff --git a/components/strings/components_strings_es-419.xtb b/components/strings/components_strings_es-419.xtb index a5166aff..b4ca0a7 100644 --- a/components/strings/components_strings_es-419.xtb +++ b/components/strings/components_strings_es-419.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">ID de API de directorio:</translation> <translation id="2597378329261239068">Este documento está protegido por contraseña. Ingresa una contraseña.</translation> <translation id="2609632851001447353">Variaciones</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Ninguna}=1{1 app ($1)}=2{2 apps ($1, $2)}other{# apps ($1, $2, $3)}}</translation> <translation id="2625385379895617796">El reloj está adelantado</translation> <translation id="2634124572758952069">No se pudo encontrar la dirección IP del servidor de <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">Estado:</translation>
diff --git a/components/strings/components_strings_es.xtb b/components/strings/components_strings_es.xtb index a1703e1..be6aed3f1 100644 --- a/components/strings/components_strings_es.xtb +++ b/components/strings/components_strings_es.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">ID de la API del directorio:</translation> <translation id="2597378329261239068">Este documento está protegido por contraseña. Introduce una contraseña.</translation> <translation id="2609632851001447353">Variaciones</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Ninguna}=1{1 aplicación ($1)}=2{2 aplicaciones ($1 y $2)}other{# aplicaciones ($1, $2 y $3)}}</translation> <translation id="2625385379895617796">Tu reloj está adelantado</translation> <translation id="2634124572758952069">No se ha podido encontrar la dirección IP del servidor de <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">Estado:</translation>
diff --git a/components/strings/components_strings_et.xtb b/components/strings/components_strings_et.xtb index 5ddb482..ea657de5 100644 --- a/components/strings/components_strings_et.xtb +++ b/components/strings/components_strings_et.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Kataloogi API ID:</translation> <translation id="2597378329261239068">Dokument on parooliga kaitstud. Sisestage parool.</translation> <translation id="2609632851001447353">Variatsioonid</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Ühtegi}=1{1 rakendus ($1)}=2{2 rakendust ($1, $2)}other{# rakendust ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Teie kell on ees</translation> <translation id="2634124572758952069">Hosti <ph name="HOST_NAME" /> serveri IP-aadressi ei leitud.</translation> <translation id="2639739919103226564">Olek:</translation>
diff --git a/components/strings/components_strings_fa.xtb b/components/strings/components_strings_fa.xtb index f7be86f..fc642b4 100644 --- a/components/strings/components_strings_fa.xtb +++ b/components/strings/components_strings_fa.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">شناسه Directory API:</translation> <translation id="2597378329261239068">این سند توسط گذرواژه محافظت میشود. لطفاً یک گذرواژه وارد کنید.</translation> <translation id="2609632851001447353">انواع مختلف</translation> -<translation id="262424810616849754">{COUNT,plural, =0{هیچکدام}=1{۱ برنامه ($1)}=2{۲ برنامه ($1، $2)}one{# برنامه ($1، $2، $3)}other{# برنامه ($1، $2، $3)}}</translation> <translation id="2625385379895617796">ساعت شما جلو است</translation> <translation id="2634124572758952069">نشانی IP سرور <ph name="HOST_NAME" /> پیدا نشد.</translation> <translation id="2639739919103226564">وضعیت:</translation>
diff --git a/components/strings/components_strings_fi.xtb b/components/strings/components_strings_fi.xtb index c2a91d3..02bcd1aa 100644 --- a/components/strings/components_strings_fi.xtb +++ b/components/strings/components_strings_fi.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Hakemistosovellusliittymän tunnus:</translation> <translation id="2597378329261239068">Tämä asiakirja on suojattu salasanalla. Anna salasana.</translation> <translation id="2609632851001447353">Muunnelmat</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Ei mitään}=1{1 sovellus ($1)}=2{2 sovellusta ($1 ja $2)}other{# sovellusta ($1, $2 ja $3)}}</translation> <translation id="2625385379895617796">Kellosi edistää</translation> <translation id="2634124572758952069">Sivuston <ph name="HOST_NAME" /> palvelimen IP-osoitetta ei löytynyt.</translation> <translation id="2639739919103226564">Tila:</translation>
diff --git a/components/strings/components_strings_fil.xtb b/components/strings/components_strings_fil.xtb index b9eb4a0..3336dbb1 100644 --- a/components/strings/components_strings_fil.xtb +++ b/components/strings/components_strings_fil.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Directory API ID:</translation> <translation id="2597378329261239068">Protektado ng password ang dokumentong ito. Mangyaring magpasok ng password.</translation> <translation id="2609632851001447353">Mga Pagkakaiba-iba</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Wala}=1{1 app ($1)}=2{2 app ($1, $2)}one{# app ($1, $2, $3)}other{# na app ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Nauuna ang iyong orasan</translation> <translation id="2634124572758952069">Hindi makita ang IP address ng server ng <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">Katayuan:</translation>
diff --git a/components/strings/components_strings_fr.xtb b/components/strings/components_strings_fr.xtb index 9ee9054..c9cdccb 100644 --- a/components/strings/components_strings_fr.xtb +++ b/components/strings/components_strings_fr.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">ID de l'API d'annuaire :</translation> <translation id="2597378329261239068">Ce document est protégé par mot de passe. Veuillez saisir ce dernier.</translation> <translation id="2609632851001447353">Variantes</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Aucune}=1{1 application ($1)}=2{2 applications ($1, $2)}one{# application ($1, $2 $3)}other{# applications ($1, $2 $3)}}</translation> <translation id="2625385379895617796">Votre horloge est en avance.</translation> <translation id="2634124572758952069">Impossible de trouver l'adresse IP du serveur de <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">État :</translation>
diff --git a/components/strings/components_strings_gu.xtb b/components/strings/components_strings_gu.xtb index 86ca815b..e349800e 100644 --- a/components/strings/components_strings_gu.xtb +++ b/components/strings/components_strings_gu.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">ડિરેક્ટરી API ID:</translation> <translation id="2597378329261239068">આ દસ્તાવેજ પાસવર્ડ સુરક્ષિત છે. કૃપા કરીને પાસવર્ડ દાખલ કરો.</translation> <translation id="2609632851001447353">વૈવિધ્ય</translation> -<translation id="262424810616849754">{COUNT,plural, =0{કોઈ નહીં}=1{1 ઍપ્લિકેશન ($1)}=2{2 ઍપ્લિકેશનો ($1, $2)}one{# ઍપ્લિકેશનો ($1, $2, $3)}other{# ઍપ્લિકેશનો ($1, $2, $3)}}</translation> <translation id="2625385379895617796">તમારી ઘડિયાળ આગળ છે</translation> <translation id="2634124572758952069"><ph name="HOST_NAME" />નું સર્વર IP ઍડ્રેસ ન મળ્યું.</translation> <translation id="2639739919103226564">સ્થિતિ:</translation>
diff --git a/components/strings/components_strings_hi.xtb b/components/strings/components_strings_hi.xtb index 84569bb..c24d73e 100644 --- a/components/strings/components_strings_hi.xtb +++ b/components/strings/components_strings_hi.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">निर्देशिका API (एपीआई) आईडी:</translation> <translation id="2597378329261239068">यह दस्तावेज़ पासवर्ड सुरक्षित है. कृपया पासवर्ड डालें.</translation> <translation id="2609632851001447353">विविधताएं</translation> -<translation id="262424810616849754">{COUNT,plural, =0{कुछ नहीं}=1{1 ऐप्लिकेशन ($1)}=2{2 ऐप्लिकेशन ($1, $2)}one{# ऐप्लिकेशन ($1, $2, $3)}other{# ऐप्लिकेशन ($1, $2, $3)}}</translation> <translation id="2625385379895617796">आपकी घड़ी आगे है</translation> <translation id="2634124572758952069"><ph name="HOST_NAME" /> का सर्वर आईपी पता नहीं मिल सका.</translation> <translation id="2639739919103226564">स्थिति:</translation>
diff --git a/components/strings/components_strings_hr.xtb b/components/strings/components_strings_hr.xtb index 6596e919..138892f 100644 --- a/components/strings/components_strings_hr.xtb +++ b/components/strings/components_strings_hr.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">ID API-ja direktorija:</translation> <translation id="2597378329261239068">Ovaj je dokument zaštićen zaporkom. Unesite zaporku.</translation> <translation id="2609632851001447353">Varijacije</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Nijedna}=1{1 aplikacija ($1)}=2{2 aplikacije ($1, $2)}one{# aplikacija ($1, $2, $3)}few{# aplikacije ($1, $2, $3)}other{# aplikacija ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Sat ide unaprijed</translation> <translation id="2634124572758952069">IP adresa poslužitelja hosta <ph name="HOST_NAME" /> nije pronađena.</translation> <translation id="2639739919103226564">Status:</translation>
diff --git a/components/strings/components_strings_hu.xtb b/components/strings/components_strings_hu.xtb index b7ca30b..dc4df12 100644 --- a/components/strings/components_strings_hu.xtb +++ b/components/strings/components_strings_hu.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Könyvtár API-azonosítója:</translation> <translation id="2597378329261239068">Ez a dokumentum jelszóval védett. Kérjük, adja meg a jelszót.</translation> <translation id="2609632851001447353">Változatok</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Nincs}=1{1 alkalmazás ($1)}=2{2 alkalmazás ($1, $2)}other{# alkalmazás ($1, $2 $3)}}</translation> <translation id="2625385379895617796">Az órája siet</translation> <translation id="2634124572758952069">A(z) <ph name="HOST_NAME" /> szerver IP-címe nem található.</translation> <translation id="2639739919103226564">Állapot:</translation>
diff --git a/components/strings/components_strings_id.xtb b/components/strings/components_strings_id.xtb index 4855ad4..a5f494d 100644 --- a/components/strings/components_strings_id.xtb +++ b/components/strings/components_strings_id.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">ID API Direktori:</translation> <translation id="2597378329261239068">Dokumen ini dilindungi sandi. Masukkan sandi.</translation> <translation id="2609632851001447353">Variasi</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Tidak ada}=1{1 aplikasi ($1)}=2{2 aplikasi ($1, $2)}other{# aplikasi ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Setelan jam terlalu cepat</translation> <translation id="2634124572758952069">Alamat IP server <ph name="HOST_NAME" /> tidak dapat ditemukan.</translation> <translation id="2639739919103226564">Status:</translation>
diff --git a/components/strings/components_strings_it.xtb b/components/strings/components_strings_it.xtb index 29802871..38b9670 100644 --- a/components/strings/components_strings_it.xtb +++ b/components/strings/components_strings_it.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">ID API Directory:</translation> <translation id="2597378329261239068">Questo documento è protetto da password. Inserisci una password.</translation> <translation id="2609632851001447353">Varianti</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Nessuna}=1{1 app ($1)}=2{2 app ($1, $2)}other{# app ($1, $2, $3)}}</translation> <translation id="2625385379895617796">L'orologio è avanti</translation> <translation id="2634124572758952069">Impossibile trovare l'indirizzo IP del server di <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">Stato:</translation> @@ -654,7 +653,7 @@ <translation id="5344579389779391559">Questa pagina potrebbe tentare di addebitarti dei costi</translation> <translation id="5355557959165512791">Al momento non puoi visitare il sito <ph name="SITE" /> perché il relativo certificato è stato revocato. In genere gli errori di rete e gli attacchi sono temporanei, pertanto questa pagina potrebbe funzionare più tardi.</translation> <translation id="536296301121032821">Archiviazione delle impostazioni criterio non riuscita</translation> -<translation id="5363056109122666249">Chrome chiede se vuoi salvare le tue carte nel tuo Account Google poiché ora sei collegato all'account. Puoi modificare questo comportamento nelle impostazioni.</translation> +<translation id="5363056109122666249">Chrome chiede se vuoi salvare le tue carte nel tuo Account Google poiché hai effettuato l'accesso all'account. Puoi modificare questo comportamento nelle impostazioni.</translation> <translation id="5371425731340848620">Aggiorna carta</translation> <translation id="5377026284221673050">"L'orologio è indietro", "L'orologio è avanti" oppure "<span class="error-code">NET::ERR_CERT_DATE_INVALID</span>"</translation> <translation id="5384855140246857529">Accedi e attiva la sincronizzazione per utilizzare le tue carte su tutti i dispositivi.</translation>
diff --git a/components/strings/components_strings_iw.xtb b/components/strings/components_strings_iw.xtb index c2be5804..f5bee9c 100644 --- a/components/strings/components_strings_iw.xtb +++ b/components/strings/components_strings_iw.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">מזהה ממשק API של ספרייה:</translation> <translation id="2597378329261239068">מסמך זה מוגן באמצעות סיסמה. הזן סיסמה.</translation> <translation id="2609632851001447353">וריאציות</translation> -<translation id="262424810616849754">{COUNT,plural, =0{ללא}=1{אפליקציה אחת (1$)}=2{שתי אפליקציות ($1, $2)}many{# אפליקציות ($1, $2, $3)}other{# אפליקציות ($1, $2, $3)}}</translation> <translation id="2625385379895617796">השעון שלך מקדים</translation> <translation id="2634124572758952069">לא ניתן היה למצוא את כתובת ה-IP של השרת של <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">סטטוס:</translation>
diff --git a/components/strings/components_strings_ja.xtb b/components/strings/components_strings_ja.xtb index c2b4ea3..624bfc3 100644 --- a/components/strings/components_strings_ja.xtb +++ b/components/strings/components_strings_ja.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Directory API ID:</translation> <translation id="2597378329261239068">このドキュメントはパスワードで保護されています。パスワードを入力してください。</translation> <translation id="2609632851001447353">バリエーション</translation> -<translation id="262424810616849754">{COUNT,plural, =0{なし}=1{1 個のアプリ($1)}=2{2 個のアプリ($1、$2)}other{# 個のアプリ($1、$2、$3)}}</translation> <translation id="2625385379895617796">時計が進んでいます</translation> <translation id="2634124572758952069"><ph name="HOST_NAME" /> のサーバーの IP アドレスが見つかりませんでした。</translation> <translation id="2639739919103226564">ステータス:</translation> @@ -760,7 +759,7 @@ <translation id="6047233362582046994">有害なアプリがまだ存在する可能性があるにもかかわらず<ph name="BEGIN_LINK" />このサイトにアクセスする<ph name="END_LINK" />場合は、セキュリティ上の危険性をあらかじめご認識ください。</translation> <translation id="6047927260846328439">アクセス先のコンテンツは、ユーザーをだましてソフトウェアをインストールさせようとしたり、個人情報を危険にさらしたりする可能性があります。<ph name="BEGIN_LINK" />危険性を理解したうえで表示する<ph name="END_LINK" /></translation> <translation id="6051221802930200923"><ph name="SITE" /> では証明書ピンニングが使用されているため、現在アクセスできません。通常、ネットワーク エラーやネットワークへの攻撃は一時的なものです。しばらくするとページにアクセスできるようになります。</translation> -<translation id="6058977677006700226">お使いのどの端末でも同じカードを使用できるようにしかすか?</translation> +<translation id="6058977677006700226">お使いのどのデバイスでも同じカードを使用できるようにしかすか?</translation> <translation id="6059925163896151826">USB デバイス</translation> <translation id="6071091556643036997">ポリシーのタイプが無効です。</translation> <translation id="6080696365213338172">管理者が提供する証明書を使用してコンテンツにアクセスしています。<ph name="DOMAIN" /> に提供するデータは管理者によって傍受される可能性があります。</translation> @@ -990,7 +989,7 @@ <translation id="7681101578153515023">検索エンジンを変更する</translation> <translation id="7682287625158474539">発送先</translation> <translation id="7687186412095877299">保存したお支払い方法を使ってお支払いフォームに入力する</translation> -<translation id="769721561045429135">現在、この端末でのみ使用できるカードがあります。カードを確認するには [続行] をクリックしてください。</translation> +<translation id="769721561045429135">現在、このデバイスでのみ使用できるカードがあります。カードを確認するには [続行] をクリックしてください。</translation> <translation id="7699293099605015246">記事は現在利用できません</translation> <translation id="7701040980221191251">なし</translation> <translation id="7704050614460855821"><ph name="BEGIN_LINK" /><ph name="SITE" /> にアクセスする(安全ではありません)<ph name="END_LINK" /></translation>
diff --git a/components/strings/components_strings_kn.xtb b/components/strings/components_strings_kn.xtb index c479f7e..253ef84 100644 --- a/components/strings/components_strings_kn.xtb +++ b/components/strings/components_strings_kn.xtb
@@ -254,7 +254,6 @@ <translation id="2587841377698384444">ಡೈರೆಕ್ಟರಿ API ID:</translation> <translation id="2597378329261239068">ಈ ಡಾಕ್ಯುಮೆಂಟ್ ಅನ್ನು ಪಾಸ್ವರ್ಡ್ನಿಂದ ರಕ್ಷಿಸಲಾಗಿದೆ. ದಯವಿಟ್ಟು ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ನಮೂದಿಸಿ.</translation> <translation id="2609632851001447353">ಪರಿವರ್ತನೆಗಳು</translation> -<translation id="262424810616849754">{COUNT,plural, =0{ಯಾವುದೂ ಇಲ್ಲ}=1{1 ಅಪ್ಲಿಕೇಶನ್ ($1)}=2{2 ಅಪ್ಲಿಕೇಶನ್ಗಳು ($1, $2)}one{# ಅಪ್ಲಿಕೇಶನ್ಗಳು ($1, $2, $3)}other{# ಅಪ್ಲಿಕೇಶನ್ಗಳು ($1, $2, $3)}}</translation> <translation id="2625385379895617796">ನಿಮ್ಮ ಗಡಿಯಾರವು ಮುಂದೆ ಇದೆ</translation> <translation id="2634124572758952069"><ph name="HOST_NAME" /> ನ ಸರ್ವರ್ IP ವಿಳಾಸ ಕಂಡುಬರಲಿಲ್ಲ.</translation> <translation id="2639739919103226564">ಸ್ಥಿತಿ: </translation>
diff --git a/components/strings/components_strings_ko.xtb b/components/strings/components_strings_ko.xtb index 38a7a4cc..c84f9a8 100644 --- a/components/strings/components_strings_ko.xtb +++ b/components/strings/components_strings_ko.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Directory API ID:</translation> <translation id="2597378329261239068">문서가 비밀번호로 보호되고 있습니다. 비밀번호를 입력하세요.</translation> <translation id="2609632851001447353">유사 버전</translation> -<translation id="262424810616849754">{COUNT,plural, =0{없음}=1{앱 1개($1)}=2{앱 2개($1, $2)}other{앱 #개($1, $2, $3)}}</translation> <translation id="2625385379895617796">시간이 너무 먼 미래로 설정되어 있습니다.</translation> <translation id="2634124572758952069"><ph name="HOST_NAME" />의 서버 IP 주소를 찾을 수 없습니다.</translation> <translation id="2639739919103226564">상태:</translation>
diff --git a/components/strings/components_strings_lt.xtb b/components/strings/components_strings_lt.xtb index dd28d0c..d7668fc 100644 --- a/components/strings/components_strings_lt.xtb +++ b/components/strings/components_strings_lt.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Katalogo API ID:</translation> <translation id="2597378329261239068">Šis dokumentas apsaugotas slaptažodžiu. Įveskite slaptažodį.</translation> <translation id="2609632851001447353">Variantai</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Nėra}=1{1 programa („$1“)}=2{2 programos („$1“, „$2“)}one{# programa („$1“, „$2“, „$3“)}few{# programos („$1“, „$2“, „$3“)}many{# programos („$1“, „$2“, „$3“)}other{# programų („$1“, „$2“, „$3“)}}</translation> <translation id="2625385379895617796">Jūsų laikrodis skuba</translation> <translation id="2634124572758952069">Nepavyko rasti <ph name="HOST_NAME" /> serverio IP adreso.</translation> <translation id="2639739919103226564">Būsena:</translation>
diff --git a/components/strings/components_strings_lv.xtb b/components/strings/components_strings_lv.xtb index ca262dd1..49e7b15 100644 --- a/components/strings/components_strings_lv.xtb +++ b/components/strings/components_strings_lv.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Direktorija API ID:</translation> <translation id="2597378329261239068">Šis dokuments ir aizsargāts ar paroli. Lūdzu, ievadiet paroli.</translation> <translation id="2609632851001447353">Varianti</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Nav}=1{1 lietotne ($1)}=2{2 lietotnes ($1, $2)}zero{# lietotnes ($1, $2, $3)}one{# lietotne ($1, $2, $3)}other{# lietotnes ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Norādītais laiks ir pārāk tālu nākotnē</translation> <translation id="2634124572758952069">Nevarēja atrast vietnes <ph name="HOST_NAME" /> servera IP adresi.</translation> <translation id="2639739919103226564">Statuss:</translation>
diff --git a/components/strings/components_strings_ml.xtb b/components/strings/components_strings_ml.xtb index 3cb17d0..26d1db8 100644 --- a/components/strings/components_strings_ml.xtb +++ b/components/strings/components_strings_ml.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">ഡയറക്ടറി API ഐഡി:</translation> <translation id="2597378329261239068">ഈ പ്രമാണം പാസ്വേഡ് പരിരക്ഷിതമാണ്. ദയവായി ഒരു പാസ്വേഡ് നല്കുക.</translation> <translation id="2609632851001447353">വേരിയേഷനുകൾ</translation> -<translation id="262424810616849754">{COUNT,plural, =0{ഒന്നുമില്ല}=1{ഒരു ആപ്പ് ($1)}=2{2 ആപ്സ് ($1, $2)}other{# ആപ്സ് ($1, $2, $3)}}</translation> <translation id="2625385379895617796">നിങ്ങളുടെ ക്ലോക്ക് വളരെ മുമ്പിലാണ്</translation> <translation id="2634124572758952069"><ph name="HOST_NAME" />-ന്റെ സെർവർ IP വിലാസം കണ്ടെത്താനായില്ല.</translation> <translation id="2639739919103226564">നില:</translation>
diff --git a/components/strings/components_strings_mr.xtb b/components/strings/components_strings_mr.xtb index 483e382..632a6ae 100644 --- a/components/strings/components_strings_mr.xtb +++ b/components/strings/components_strings_mr.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">शब्दकोश API आयडी:</translation> <translation id="2597378329261239068">हा दस्तऐवज पासवर्ड संरक्षित आहे. कृपया पासवर्ड एंटर करा.</translation> <translation id="2609632851001447353">तफावत</translation> -<translation id="262424810616849754">{COUNT,plural, =0{काहीही नाही}=1{1 अॅप ($1)}=2{2 अॅप्स ($1, $2)}one{# अॅप् ($1, $2, $3)}other{# अॅप्स ($1, $2, $3)}}</translation> <translation id="2625385379895617796">तुमचे घड्याळ पुढे आहे</translation> <translation id="2634124572758952069"><ph name="HOST_NAME" /> चा सर्व्हर आयपी अॅड्रेस सापडला नाही.</translation> <translation id="2639739919103226564">स्थिती:</translation>
diff --git a/components/strings/components_strings_ms.xtb b/components/strings/components_strings_ms.xtb index 982a0d7e..c5023cb 100644 --- a/components/strings/components_strings_ms.xtb +++ b/components/strings/components_strings_ms.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">ID API Direktori:</translation> <translation id="2597378329261239068">Dokumen ini dilindungi kata laluan. Sila masukkan kata laluan.</translation> <translation id="2609632851001447353">Variasi</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Tiada}=1{1 apl ($1)}=2{2 apl ($1, $2)}other{# apl ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Jam anda lebih awal</translation> <translation id="2634124572758952069">Alamat IP pelayan <ph name="HOST_NAME" /> tidak ditemui.</translation> <translation id="2639739919103226564">Status:</translation>
diff --git a/components/strings/components_strings_nl.xtb b/components/strings/components_strings_nl.xtb index f3d3b566..1b8d0a5 100644 --- a/components/strings/components_strings_nl.xtb +++ b/components/strings/components_strings_nl.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Directory API-ID:</translation> <translation id="2597378329261239068">Dit document is beveiligd met een wachtwoord. Geef een wachtwoord op.</translation> <translation id="2609632851001447353">Varianten</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Geen}=1{1 app ($1)}=2{2 apps ($1, $2)}other{# apps ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Je klok loopt voor</translation> <translation id="2634124572758952069">Het IP-adres van de server van <ph name="HOST_NAME" /> kan niet worden gevonden.</translation> <translation id="2639739919103226564">Status:</translation>
diff --git a/components/strings/components_strings_no.xtb b/components/strings/components_strings_no.xtb index a22603f..c250f2c 100644 --- a/components/strings/components_strings_no.xtb +++ b/components/strings/components_strings_no.xtb
@@ -244,7 +244,7 @@ <translation id="2501278716633472235">Gå tilbake</translation> <translation id="2503184589641749290">Godkjente debetkort og forhåndsbetalte kort</translation> <translation id="2515629240566999685">Sjekk signalet i området ditt</translation> -<translation id="2523886232349826891">Kun lagret på denne enheten.</translation> +<translation id="2523886232349826891">Kun lagret på denne enheten</translation> <translation id="2524461107774643265">Legg til mer informasjon</translation> <translation id="2536110899380797252">Legg til adresse</translation> <translation id="2539524384386349900">Oppdag</translation> @@ -255,7 +255,6 @@ <translation id="2587841377698384444">ID for katalog-API:</translation> <translation id="2597378329261239068">Dette dokumentet er passordbeskyttet. Skriv inn et passord.</translation> <translation id="2609632851001447353">Varianter</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Ingen}=1{1 app ($1)}=2{2 apper ($1, $2)}other{# apper ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Klokken går for fort</translation> <translation id="2634124572758952069">Fant ikke IP-adressen til tjeneren for <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">Status:</translation>
diff --git a/components/strings/components_strings_pl.xtb b/components/strings/components_strings_pl.xtb index 2536e7e..c7ec7baf 100644 --- a/components/strings/components_strings_pl.xtb +++ b/components/strings/components_strings_pl.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Identyfikator interfejsu API katalogu:</translation> <translation id="2597378329261239068">Ten dokument jest chroniony hasłem. Wprowadź hasło.</translation> <translation id="2609632851001447353">Odmiany</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Brak}=1{1 aplikacja ($1)}=2{2 aplikacje ($1, $2)}few{# aplikacje ($1, $2, $3)}many{# aplikacji ($1, $2, $3)}other{# aplikacji ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Twój zegar się śpieszy</translation> <translation id="2634124572758952069">Nie udało się znaleźć adresu IP serwera ze stroną <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">Stan:</translation> @@ -990,7 +989,7 @@ <translation id="7681101578153515023">Zmień wyszukiwarkę</translation> <translation id="7682287625158474539">Adres wysyłkowy</translation> <translation id="7687186412095877299">Wypełniaj formularze płatności, używając zapisanych form płatności</translation> -<translation id="769721561045429135">Obecnie niektórych Twoich kart można używać tylko na tym urządzeniu. Kliknij Dalej, by wyświetlić karty.</translation> +<translation id="769721561045429135">Obecnie niektórych z Twoich kart można używać tylko na tym urządzeniu. Kliknij Dalej, by wyświetlić karty.</translation> <translation id="7699293099605015246">Artykuły nie są obecnie dostępne</translation> <translation id="7701040980221191251">Brak</translation> <translation id="7704050614460855821"><ph name="BEGIN_LINK" />Otwórz stronę <ph name="SITE" /> (niebezpieczną)<ph name="END_LINK" /></translation>
diff --git a/components/strings/components_strings_pt-BR.xtb b/components/strings/components_strings_pt-BR.xtb index 709178d..c104e16 100644 --- a/components/strings/components_strings_pt-BR.xtb +++ b/components/strings/components_strings_pt-BR.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Código da API do diretório:</translation> <translation id="2597378329261239068">Este documento está protegido por senha. Digite a senha.</translation> <translation id="2609632851001447353">Variações</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Nenhum}=1{1 app ($1)}=2{2 apps ($1, $2)}one{# app ($1)}other{# apps ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Seu relógio está adiantado</translation> <translation id="2634124572758952069">Não foi possível encontrar o endereço IP do servidor de <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">Status:</translation>
diff --git a/components/strings/components_strings_pt-PT.xtb b/components/strings/components_strings_pt-PT.xtb index 4d091bd..d984267 100644 --- a/components/strings/components_strings_pt-PT.xtb +++ b/components/strings/components_strings_pt-PT.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">ID da API de diretório:</translation> <translation id="2597378329261239068">Este documento está protegido por palavra-passe. Introduza uma palavra-passe.</translation> <translation id="2609632851001447353">Variações</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Nenhuma}=1{1 aplicação ($1)}=2{2 aplicações ($1, $2)}other{# aplicações ($1, $2, $3)}}</translation> <translation id="2625385379895617796">O seu relógio está adiantado</translation> <translation id="2634124572758952069">Não foi possível encontrar o endereço IP do servidor de <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">Estado:</translation>
diff --git a/components/strings/components_strings_ro.xtb b/components/strings/components_strings_ro.xtb index 1946ae3c..1fe9db1 100644 --- a/components/strings/components_strings_ro.xtb +++ b/components/strings/components_strings_ro.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">ID-ul API-ului Directory:</translation> <translation id="2597378329261239068">Acest document este protejat cu parolă. Introdu o parolă.</translation> <translation id="2609632851001447353">Modificări</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Niciuna}=1{1 aplicație ($1)}=2{2 aplicații ($1, $2)}few{# aplicații ($1, $2, $3)}other{# de aplicații ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Ora este setată în viitor</translation> <translation id="2634124572758952069">Nu s-a găsit adresa IP pentru serverul <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">Stare:</translation>
diff --git a/components/strings/components_strings_ru.xtb b/components/strings/components_strings_ru.xtb index 1ddcd5e..db402b0a 100644 --- a/components/strings/components_strings_ru.xtb +++ b/components/strings/components_strings_ru.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Идентификатор Directory API:</translation> <translation id="2597378329261239068">Документ защищен паролем. Введите пароль.</translation> <translation id="2609632851001447353">Варианты</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Нет}=1{1 приложение ($1)}=2{2 приложения ($1 и $2)}one{# приложение ($1, $2 $3)}few{# приложения ($1, $2 $3)}many{# приложений ($1, $2 $3)}other{# приложения ($1, $2 $3)}}</translation> <translation id="2625385379895617796">Часы спешат</translation> <translation id="2634124572758952069">Не удалось найти IP-адрес сервера <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">Состояние:</translation>
diff --git a/components/strings/components_strings_sk.xtb b/components/strings/components_strings_sk.xtb index d7ec8cf..c37dcc2 100644 --- a/components/strings/components_strings_sk.xtb +++ b/components/strings/components_strings_sk.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Identifikátor priečinka API:</translation> <translation id="2597378329261239068">Tento dokument je chránený heslom. Zadajte heslo.</translation> <translation id="2609632851001447353">Variácie</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Žiadne}=1{1 aplikácia ($1)}=2{2 aplikácie ($1, $2)}few{# aplikácie ($1, $2, $3)}many{# aplikácie ($1, $2, $3)}other{# aplikácií ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Vaše hodiny idú dopredu</translation> <translation id="2634124572758952069">Adresu IP servera <ph name="HOST_NAME" /> sa nepodarilo nájsť.</translation> <translation id="2639739919103226564">Stav:</translation> @@ -985,7 +984,7 @@ <translation id="7681101578153515023">Zmeniť vyhľadávač</translation> <translation id="7682287625158474539">Dodacia</translation> <translation id="7687186412095877299">Doplní do platobných formulárov vaše uložené spôsoby platby</translation> -<translation id="769721561045429135">Momentálne máte karty, ktorú je možné použiť iba v tomto zariadení Ak chcete skontrolovať karty, kliknite na Pokračovať.</translation> +<translation id="769721561045429135">Momentálne máte karty, ktoré je možné použiť iba v tomto zariadení Ak chcete skontrolovať karty, kliknite na Pokračovať.</translation> <translation id="7699293099605015246">Články nie sú momentálne k dispozícii</translation> <translation id="7701040980221191251">Žiadne</translation> <translation id="7704050614460855821"><ph name="BEGIN_LINK" />Prejsť na stránky <ph name="SITE" /> (nebezpečné)<ph name="END_LINK" /></translation>
diff --git a/components/strings/components_strings_sl.xtb b/components/strings/components_strings_sl.xtb index 7640a9d..3846983 100644 --- a/components/strings/components_strings_sl.xtb +++ b/components/strings/components_strings_sl.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">ID API-ja imenika:</translation> <translation id="2597378329261239068">Dokument je zaščiten z geslom. Vnesite geslo.</translation> <translation id="2609632851001447353">Različice</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Brez}=1{1 aplikacija ($1)}=2{2 aplikaciji ($1, $2)}one{# aplikacija ($1, $2, $3)}two{# aplikaciji ($1, $2, $3)}few{# aplikacije ($1, $2, $3)}other{# aplikacij ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Ura prehiteva</translation> <translation id="2634124572758952069">Naslova IP strežnika <ph name="HOST_NAME" /> ni bilo mogoče najti.</translation> <translation id="2639739919103226564">Stanje:</translation>
diff --git a/components/strings/components_strings_sr.xtb b/components/strings/components_strings_sr.xtb index 98295699..f816701a 100644 --- a/components/strings/components_strings_sr.xtb +++ b/components/strings/components_strings_sr.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">ИД API-ја за директоријуме:</translation> <translation id="2597378329261239068">Овај документ је заштићен лозинком. Унесите лозинку.</translation> <translation id="2609632851001447353">Варијације</translation> -<translation id="262424810616849754">{COUNT,plural, =0{None}=1{1 апликација ($1)}=2{2 апликације ($1, $2)}one{# апликација ($1, $2, $3)}few{# апликације ($1, $2, $3)}other{# апликација ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Сат вам жури</translation> <translation id="2634124572758952069">Нисмо успели да пронађемо IP адресу сервера хоста <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">Статус:</translation>
diff --git a/components/strings/components_strings_sv.xtb b/components/strings/components_strings_sv.xtb index 938c72ba..6b4877b 100644 --- a/components/strings/components_strings_sv.xtb +++ b/components/strings/components_strings_sv.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Id för katalog-API:</translation> <translation id="2597378329261239068">Dokumentet är lösenordsskyddat. Ange ett lösenord.</translation> <translation id="2609632851001447353">Varianter</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Ingen}=1{1 app ($1)}=2{2 appar ($1, $2)}other{# appar ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Klockan går före</translation> <translation id="2634124572758952069">Det gick inte att hitta IP-adressen till servern på <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">Status:</translation>
diff --git a/components/strings/components_strings_sw.xtb b/components/strings/components_strings_sw.xtb index 034a96c..7958ae7c 100644 --- a/components/strings/components_strings_sw.xtb +++ b/components/strings/components_strings_sw.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Kitambulisho cha API ya Saraka:</translation> <translation id="2597378329261239068">Hati hii imelindwa kwa nenosiri. Tafadhali weka nenosiri linalotumika.</translation> <translation id="2609632851001447353">Vipera</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Hamna}=1{Programu 1 ($1)}=2{Programu 2 ($1, $2)}other{Programu # ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Saa yako iko mbele</translation> <translation id="2634124572758952069">Haikupata anwani ya IP ya seva ya <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">Hali:</translation>
diff --git a/components/strings/components_strings_ta.xtb b/components/strings/components_strings_ta.xtb index e4ea725..9fef2fa 100644 --- a/components/strings/components_strings_ta.xtb +++ b/components/strings/components_strings_ta.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">கோப்பக API ஐடி:</translation> <translation id="2597378329261239068">இந்த ஆவணம் கடவுச்சொல் பாதுகாக்கப்பட்ட ஒன்று. தயவுசெய்து ஒரு கடவுச்சொல்லை உள்ளிடுக.</translation> <translation id="2609632851001447353">வேறுபாடுகள்</translation> -<translation id="262424810616849754">{COUNT,plural, =0{ஏதுமில்லை}=1{1 பயன்பாடு ($1)}=2{2 பயன்பாடுகள் ($1, $2)}other{# பயன்பாடுகள் ($1, $2, $3)}}</translation> <translation id="2625385379895617796">உங்கள் கடிகாரம் மிகவும் முன்னோக்கி இருக்கிறது</translation> <translation id="2634124572758952069"><ph name="HOST_NAME" /> இன் சேவையக IP முகவரியைக் கண்டறிய முடியவில்லை.</translation> <translation id="2639739919103226564">நிலை:</translation>
diff --git a/components/strings/components_strings_te.xtb b/components/strings/components_strings_te.xtb index 22dedf1..6e7f907 100644 --- a/components/strings/components_strings_te.xtb +++ b/components/strings/components_strings_te.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">డైరెక్టరీ API ID:</translation> <translation id="2597378329261239068">ఈ పత్రం అనుమతి పదంచే రక్షించబడింది. దయచేసి అనుమతి పదాన్ని నమోదు చేయండి.</translation> <translation id="2609632851001447353">వ్యత్యాసాలు</translation> -<translation id="262424810616849754">{COUNT,plural, =0{ఏమీ లేవు}=1{1 అనువర్తనం ($1)}=2{2 అనువర్తనాలు ($1, $2)}other{# అనువర్తనాలు ($1, $2, $3)}}</translation> <translation id="2625385379895617796">మీ గడియారం సమయం భవిష్యత్తులో ఉంది</translation> <translation id="2634124572758952069"><ph name="HOST_NAME" /> యొక్క సర్వర్ IP చిరునామా కనుగొనబడలేదు.</translation> <translation id="2639739919103226564">స్థితి: </translation>
diff --git a/components/strings/components_strings_th.xtb b/components/strings/components_strings_th.xtb index 2b58a04..5f08650 100644 --- a/components/strings/components_strings_th.xtb +++ b/components/strings/components_strings_th.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">รหัส API ไดเรกทอรี:</translation> <translation id="2597378329261239068">เอกสารนี้ได้รับการป้องกันด้วยรหัสผ่าน โปรดป้อนรหัสผ่าน</translation> <translation id="2609632851001447353">รูปแบบต่างๆ</translation> -<translation id="262424810616849754">{COUNT,plural, =0{ไม่มี}=1{1 แอป ($1)}=2{2 แอป ($1, $2)}other{# แอป ($1, $2, $3)}}</translation> <translation id="2625385379895617796">นาฬิกาเร็วเกินไป</translation> <translation id="2634124572758952069">ไม่พบที่อยู่ IP ของเซิร์ฟเวอร์ <ph name="HOST_NAME" /></translation> <translation id="2639739919103226564">สถานะ:</translation>
diff --git a/components/strings/components_strings_tr.xtb b/components/strings/components_strings_tr.xtb index d1d3fdd..1ee7101 100644 --- a/components/strings/components_strings_tr.xtb +++ b/components/strings/components_strings_tr.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Dizin API'sı Kimliği:</translation> <translation id="2597378329261239068">Doküman şifre korumalı. Lütfen şifreyi girin.</translation> <translation id="2609632851001447353">Varyasyonlar</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Yok}=1{1 uygulama ($1)}=2{2 uygulama ($1, $2)}other{# uygulama ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Saatiniz ileri</translation> <translation id="2634124572758952069"><ph name="HOST_NAME" /> ana makinesinin sunucu IP adresi bulunamadı.</translation> <translation id="2639739919103226564">Durum:</translation>
diff --git a/components/strings/components_strings_uk.xtb b/components/strings/components_strings_uk.xtb index 510a369a..4df783f 100644 --- a/components/strings/components_strings_uk.xtb +++ b/components/strings/components_strings_uk.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Ідентифікатор API каталогу:</translation> <translation id="2597378329261239068">Цей документ захищено паролем. Введіть пароль.</translation> <translation id="2609632851001447353">Різновиди</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Немає}=1{1 додаток ($1)}=2{2 додатки ($1, $2)}one{# додаток ($1, $2, $3)}few{# додатки ($1, $2, $3)}many{# додатків ($1, $2, $3)}other{# додатка ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Ваш годинник спішить</translation> <translation id="2634124572758952069">IP-адресу сервера <ph name="HOST_NAME" /> не знайдено.</translation> <translation id="2639739919103226564">Статус:</translation>
diff --git a/components/strings/components_strings_vi.xtb b/components/strings/components_strings_vi.xtb index 871067c6..eee8d12 100644 --- a/components/strings/components_strings_vi.xtb +++ b/components/strings/components_strings_vi.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">ID API thư mục:</translation> <translation id="2597378329261239068">Tài liệu này được bảo vệ bằng mật khẩu. Vui lòng nhập mật khẩu.</translation> <translation id="2609632851001447353">Các biến thể</translation> -<translation id="262424810616849754">{COUNT,plural, =0{Không có}=1{1 ứng dụng ($1)}=2{2 ứng dụng ($1, $2)}other{# ứng dụng ($1, $2, $3)}}</translation> <translation id="2625385379895617796">Đồng hồ của bạn chạy nhanh</translation> <translation id="2634124572758952069">Không thể tìm thấy địa chỉ IP của máy chủ <ph name="HOST_NAME" />.</translation> <translation id="2639739919103226564">Trạng thái:</translation>
diff --git a/components/strings/components_strings_zh-CN.xtb b/components/strings/components_strings_zh-CN.xtb index 72f04226..21474aec 100644 --- a/components/strings/components_strings_zh-CN.xtb +++ b/components/strings/components_strings_zh-CN.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Directory API ID:</translation> <translation id="2597378329261239068">本文档设置了密码保护,请输入密码。</translation> <translation id="2609632851001447353">其他变体</translation> -<translation id="262424810616849754">{COUNT,plural, =0{无}=1{1 个应用($1)}=2{2 个应用($1、$2)}other{# 个应用($1、$2,$3)}}</translation> <translation id="2625385379895617796">您的时钟快了</translation> <translation id="2634124572758952069">找不到 <ph name="HOST_NAME" /> 的服务器 IP 地址。</translation> <translation id="2639739919103226564">状态:</translation>
diff --git a/components/strings/components_strings_zh-TW.xtb b/components/strings/components_strings_zh-TW.xtb index c66ac08..c614aca 100644 --- a/components/strings/components_strings_zh-TW.xtb +++ b/components/strings/components_strings_zh-TW.xtb
@@ -255,7 +255,6 @@ <translation id="2587841377698384444">Directory API ID:</translation> <translation id="2597378329261239068">此文件受到密碼保護,請輸入密碼。</translation> <translation id="2609632851001447353">變化版本</translation> -<translation id="262424810616849754">{COUNT,plural, =0{無}=1{1 個應用程式 ($1)}=2{2 個應用程式 ($1、$2)}other{# 個應用程式 ($1、$2 $3)}}</translation> <translation id="2625385379895617796">你的時鐘時間過快</translation> <translation id="2634124572758952069">找不到 <ph name="HOST_NAME" /> 的伺服器 IP 位址。</translation> <translation id="2639739919103226564">狀態:</translation>
diff --git a/components/sync/driver/model_type_controller.cc b/components/sync/driver/model_type_controller.cc index 012a609f3..7fd22ee 100644 --- a/components/sync/driver/model_type_controller.cc +++ b/components/sync/driver/model_type_controller.cc
@@ -97,70 +97,12 @@ // Ask the delegate to actually start the datatype. delegate_->OnSyncStarting( - request, base::BindOnce(&ModelTypeController::OnProcessorStarted, + request, base::BindOnce(&ModelTypeController::OnDelegateStarted, base::AsWeakPtr(this))); } void ModelTypeController::BeforeLoadModels(ModelTypeConfigurer* configurer) {} -void ModelTypeController::LoadModelsDone(ConfigureResult result, - const SyncError& error) { - DCHECK(CalledOnValidThread()); - DCHECK_NE(NOT_RUNNING, state_); - - if (state_ == STOPPING) { - DCHECK(!model_stop_callbacks_.empty()); - - // We make a copy in case running the callbacks has side effects and - // modifies the vector, although we don't expect that in practice. - std::vector<StopCallback> model_stop_callbacks = - std::move(model_stop_callbacks_); - DCHECK(model_stop_callbacks_.empty()); - - if (IsSuccessfulResult(result)) { - state_ = NOT_RUNNING; - DVLOG(1) << "Successful sync start completion received late for " - << ModelTypeToString(type()) - << ", it has been stopped meanwhile"; - delegate_->OnSyncStopping(model_stop_metadata_fate_); - } else { - state_ = FAILED; - DVLOG(1) << "Sync start completion error received late for " - << ModelTypeToString(type()) - << ", it has been stopped meanwhile"; - } - - delegate_ = nullptr; - - for (StopCallback& stop_callback : model_stop_callbacks) { - std::move(stop_callback).Run(); - } - return; - } - - if (IsSuccessfulResult(result)) { - DCHECK_EQ(MODEL_STARTING, state_); - state_ = MODEL_LOADED; - DVLOG(1) << "Sync start completed for " << ModelTypeToString(type()); - } else { - state_ = FAILED; - } - - if (model_load_callback_) { - model_load_callback_.Run(type(), error); - } -} - -void ModelTypeController::OnProcessorStarted( - std::unique_ptr<DataTypeActivationResponse> activation_response) { - DCHECK(CalledOnValidThread()); - // Hold on to the activation context until ActivateDataType is called. - if (state_ == MODEL_STARTING) { - activation_response_ = std::move(activation_response); - } - LoadModelsDone(OK, SyncError()); -} - void ModelTypeController::RegisterWithBackend( base::OnceCallback<void(bool)> set_downloaded, ModelTypeConfigurer* configurer) { @@ -174,7 +116,7 @@ std::move(set_downloaded) .Run(activation_response_->model_type_state.initial_sync_done()); // Pass activation context to ModelTypeRegistry, where ModelTypeWorker gets - // created and connected with ModelTypeProcessor. + // created and connected with the delegate (processor). configurer->ActivateNonBlockingDataType(type(), std::move(activation_response_)); activated_ = true; @@ -261,16 +203,17 @@ DCHECK(model_stop_callbacks_.empty()); DLOG(WARNING) << "Deferring stop for " << ModelTypeToString(type()) << " because it's still starting"; + model_load_callback_.Reset(); model_stop_metadata_fate_ = metadata_fate; model_stop_callbacks_.push_back(std::move(callback)); - // The actual stop will be executed in LoadModelsDone(), when the starting - // process is finished. + // The actual stop will be executed when the starting process is finished. state_ = STOPPING; break; case MODEL_LOADED: case RUNNING: DVLOG(1) << "Stopping sync for " << ModelTypeToString(type()); + model_load_callback_.Reset(); state_ = NOT_RUNNING; delegate_->OnSyncStopping(metadata_fate); delegate_ = nullptr; @@ -343,12 +286,10 @@ NOTREACHED(); } - // TODO(jkrcal, mastiz): We should make it more strict and call - // LoadModelsDone() only if the model is actually starting as treat more cases - // above with an early return (as NOT_RUNNING). - LoadModelsDone(UNRECOVERABLE_ERROR, SyncError(error.location(), error_type, - error.message(), type())); - DCHECK_EQ(state_, FAILED); + state_ = FAILED; + + TriggerCompletionCallbacks( + SyncError(error.location(), error_type, error.message(), type())); } void ModelTypeController::RecordStartFailure() const { @@ -371,4 +312,64 @@ static_cast<int>(MODEL_TYPE_COUNT)); } +void ModelTypeController::OnDelegateStarted( + std::unique_ptr<DataTypeActivationResponse> activation_response) { + DCHECK(CalledOnValidThread()); + + switch (state_) { + case STOPPING: + DCHECK(!model_stop_callbacks_.empty()); + DCHECK(!model_load_callback_); + state_ = NOT_RUNNING; + FALLTHROUGH; + case FAILED: + DVLOG(1) << "Successful sync start completion received late for " + << ModelTypeToString(type()) + << ", it has been stopped meanwhile"; + delegate_->OnSyncStopping(model_stop_metadata_fate_); + delegate_ = nullptr; + break; + case MODEL_STARTING: + DCHECK(model_stop_callbacks_.empty()); + // Hold on to the activation context until ActivateDataType is called. + activation_response_ = std::move(activation_response); + state_ = MODEL_LOADED; + DVLOG(1) << "Sync start completed for " << ModelTypeToString(type()); + break; + case MODEL_LOADED: + case RUNNING: + case NOT_RUNNING: + case ASSOCIATING: + NOTREACHED() << " type " << ModelTypeToString(type()) << " state " + << StateToString(state_); + } + + TriggerCompletionCallbacks(SyncError()); +} + +void ModelTypeController::TriggerCompletionCallbacks(const SyncError& error) { + DCHECK(CalledOnValidThread()); + + if (model_load_callback_) { + DCHECK(model_stop_callbacks_.empty()); + DCHECK(state_ == MODEL_LOADED || state_ == FAILED); + + model_load_callback_.Run(type(), error); + } else if (!model_stop_callbacks_.empty()) { + // State FAILED is possible if an error occurred during STOPPING, either + // because the load failed or because ReportModelError() was called + // directly by a subclass. + DCHECK(state_ == NOT_RUNNING || state_ == FAILED); + + // We make a copy in case running the callbacks has side effects and + // modifies the vector, although we don't expect that in practice. + std::vector<StopCallback> model_stop_callbacks = + std::move(model_stop_callbacks_); + DCHECK(model_stop_callbacks_.empty()); + for (StopCallback& stop_callback : model_stop_callbacks) { + std::move(stop_callback).Run(); + } + } +} + } // namespace syncer
diff --git a/components/sync/driver/model_type_controller.h b/components/sync/driver/model_type_controller.h index 1e3eef2..9ba6e68 100644 --- a/components/sync/driver/model_type_controller.h +++ b/components/sync/driver/model_type_controller.h
@@ -61,17 +61,9 @@ private: void RecordStartFailure() const; void RecordRunFailure() const; - - // If the DataType controller is waiting for models to load, once the models - // are loaded this function should be called to let the base class - // implementation know that it is safe to continue with the activation. - // The error indicates whether the loading completed successfully. - void LoadModelsDone(ConfigureResult result, const SyncError& error); - - // The function will do the real work when OnProcessorStarted got called. This - // is called on the UI thread. - void OnProcessorStarted( + void OnDelegateStarted( std::unique_ptr<DataTypeActivationResponse> activation_response); + void TriggerCompletionCallbacks(const SyncError& error); base::flat_map<StorageOption, std::unique_ptr<ModelTypeControllerDelegate>> delegate_map_;
diff --git a/components/sync/driver/model_type_controller_unittest.cc b/components/sync/driver/model_type_controller_unittest.cc index 89cc522..e25f098d 100644 --- a/components/sync/driver/model_type_controller_unittest.cc +++ b/components/sync/driver/model_type_controller_unittest.cc
@@ -128,6 +128,17 @@ std::unique_ptr<ModelTypeProcessor> processor_; }; +// Class used to expose ReportModelError() publicly. +class TestModelTypeController : public ModelTypeController { + public: + explicit TestModelTypeController( + std::unique_ptr<ModelTypeControllerDelegate> delegate_on_disk) + : ModelTypeController(kTestModelType, std::move(delegate_on_disk)) {} + ~TestModelTypeController() override {} + + using ModelTypeController::ReportModelError; +}; + ConfigureContext MakeConfigureContext() { ConfigureContext context; context.authenticated_account_id = kAccountId; @@ -140,9 +151,8 @@ class ModelTypeControllerTest : public testing::Test { public: ModelTypeControllerTest() - : controller_(kTestModelType, - std::make_unique<ForwardingModelTypeControllerDelegate>( - &mock_delegate_)) {} + : controller_(std::make_unique<ForwardingModelTypeControllerDelegate>( + &mock_delegate_)) {} ~ModelTypeControllerTest() { // Since we use ModelTypeProcessorProxy, which posts tasks, make sure we @@ -210,14 +220,14 @@ MockDelegate* delegate() { return &mock_delegate_; } TestModelTypeProcessor* processor() { return &processor_; } - DataTypeController* controller() { return &controller_; } + TestModelTypeController* controller() { return &controller_; } private: base::test::ScopedTaskEnvironment task_environment_; NiceMock<MockDelegate> mock_delegate_; TestModelTypeConfigurer configurer_; TestModelTypeProcessor processor_; - ModelTypeController controller_; + TestModelTypeController controller_; }; TEST_F(ModelTypeControllerTest, InitialState) { @@ -352,8 +362,7 @@ error_handler = request.error_handler; }); - base::MockCallback<DataTypeController::ModelLoadCallback> load_models_done; - controller()->LoadModels(MakeConfigureContext(), load_models_done.Get()); + controller()->LoadModels(MakeConfigureContext(), base::DoNothing()); ASSERT_EQ(DataTypeController::MODEL_STARTING, controller()->state()); ASSERT_TRUE(error_handler); // Mimic completion for OnSyncStarting(), with an error. @@ -379,7 +388,11 @@ start_callback = std::move(callback); }); - controller()->LoadModels(MakeConfigureContext(), base::DoNothing()); + // A cancelled start never issues completion for the load. + base::MockCallback<DataTypeController::ModelLoadCallback> load_models_done; + EXPECT_CALL(load_models_done, Run(_, _)).Times(0); + + controller()->LoadModels(MakeConfigureContext(), load_models_done.Get()); ASSERT_EQ(DataTypeController::MODEL_STARTING, controller()->state()); ASSERT_TRUE(start_callback); @@ -474,6 +487,73 @@ histogram_tester.ExpectTotalCount(kRunFailuresHistogram, 0); } +// Test emulates a controller subclass issuing ReportModelError() (e.g. custom +// passphrase was enabled and the type should be disabled) while the delegate +// is starting. +TEST_F(ModelTypeControllerTest, ReportErrorWhileStarting) { + ModelTypeControllerDelegate::StartCallback start_callback; + EXPECT_CALL(*delegate(), OnSyncStarting(_, _)) + .WillOnce([&](const DataTypeActivationRequest& request, + ModelTypeControllerDelegate::StartCallback callback) { + start_callback = std::move(callback); + }); + + controller()->LoadModels(MakeConfigureContext(), base::DoNothing()); + ASSERT_EQ(DataTypeController::MODEL_STARTING, controller()->state()); + ASSERT_TRUE(start_callback); + + // The delegate should receive no OnSyncStopping() while starting despite + // the subclass issuing ReportModelError(). + EXPECT_CALL(*delegate(), OnSyncStopping(_)).Times(0); + controller()->ReportModelError(syncer::SyncError::DATATYPE_POLICY_ERROR, + ModelError(FROM_HERE, "Test error")); + EXPECT_EQ(DataTypeController::FAILED, controller()->state()); + + // Mimic completion for OnSyncStarting(). + EXPECT_CALL(*delegate(), OnSyncStopping(_)); + std::move(start_callback).Run(std::make_unique<DataTypeActivationResponse>()); + EXPECT_EQ(DataTypeController::FAILED, controller()->state()); +} + +// Test emulates a controller subclass issuing ReportModelError() (e.g. custom +// passphrase was enabled and the type should be disabled) AND the controller +// being requested to stop, both of which are received while the delegate is +// starting. +TEST_F(ModelTypeControllerTest, StopAndReportErrorWhileStarting) { + ModelTypeControllerDelegate::StartCallback start_callback; + EXPECT_CALL(*delegate(), OnSyncStarting(_, _)) + .WillOnce([&](const DataTypeActivationRequest& request, + ModelTypeControllerDelegate::StartCallback callback) { + start_callback = std::move(callback); + }); + + controller()->LoadModels(MakeConfigureContext(), base::DoNothing()); + ASSERT_EQ(DataTypeController::MODEL_STARTING, controller()->state()); + ASSERT_TRUE(start_callback); + + // The controller receives Stop() which should be deferred until + // OnSyncStarting() finishes or ReportModelError() is called. + base::MockCallback<base::OnceClosure> stop_completion; + EXPECT_CALL(stop_completion, Run()).Times(0); + EXPECT_CALL(*delegate(), OnSyncStopping(_)).Times(0); + controller()->Stop(DISABLE_SYNC, stop_completion.Get()); + EXPECT_EQ(DataTypeController::STOPPING, controller()->state()); + + // The subclass issues ReportModelError(), which should be treated as stop + // completion, but shouldn't lead to an immediate OnSyncStopping() until + // loading completes. + EXPECT_CALL(stop_completion, Run()); + EXPECT_CALL(*delegate(), OnSyncStopping(_)).Times(0); + controller()->ReportModelError(syncer::SyncError::DATATYPE_POLICY_ERROR, + ModelError(FROM_HERE, "Test error")); + EXPECT_EQ(DataTypeController::FAILED, controller()->state()); + + // Mimic completion for OnSyncStarting(). + EXPECT_CALL(*delegate(), OnSyncStopping(_)); + std::move(start_callback).Run(std::make_unique<DataTypeActivationResponse>()); + EXPECT_EQ(DataTypeController::FAILED, controller()->state()); +} + // Tests that StorageOption is honored when the controller has been constructed // with two delegates. TEST(ModelTypeControllerWithMultiDelegateTest, ToggleStorageOption) {
diff --git a/components/sync_bookmarks/bookmark_model_type_processor.cc b/components/sync_bookmarks/bookmark_model_type_processor.cc index a48d49c..4aebc03 100644 --- a/components/sync_bookmarks/bookmark_model_type_processor.cc +++ b/components/sync_bookmarks/bookmark_model_type_processor.cc
@@ -115,7 +115,11 @@ void BookmarkModelTypeProcessor::DisconnectSync() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(worker_); + + if (!worker_) { + return; + } + DVLOG(1) << "Disconnecting sync for Bookmarks"; worker_.reset(); } @@ -170,8 +174,27 @@ BookmarkModelMerger(&updates, bookmark_model_, favicon_service_, bookmark_tracker_.get()) .Merge(); - bookmark_tracker_->CheckAllNodesTracked(bookmark_model_); } + + // If any of the permanent nodes is missing, we treat it as failure. + // TODO(mamir): Revisit if this is too aggressive since it may influence + // the USS migrator case on desktop (which wouldn't usually have mobile + // bookmarks). + if (!bookmark_tracker_->GetEntityForBookmarkNode( + bookmark_model_->bookmark_bar_node()) || + !bookmark_tracker_->GetEntityForBookmarkNode( + bookmark_model_->other_node()) || + !bookmark_tracker_->GetEntityForBookmarkNode( + bookmark_model_->mobile_node())) { + StopTrackingMetadata(); + bookmark_tracker_.reset(); + error_handler_.Run( + syncer::ModelError(FROM_HERE, "Permanent bookmark entities missing")); + return; + } + + bookmark_tracker_->CheckAllNodesTracked(bookmark_model_); + schedule_save_closure_.Run(); NudgeForCommitIfNeeded(); return; @@ -288,6 +311,8 @@ cache_guid_ = request.cache_guid; start_callback_ = std::move(start_callback); + error_handler_ = request.error_handler; + DCHECK(!cache_guid_.empty()); ConnectIfReady(); } @@ -383,13 +408,7 @@ void BookmarkModelTypeProcessor::OnBookmarkModelBeingDeleted() { DCHECK(bookmark_model_); DCHECK(bookmark_model_observer_); - bookmark_model_->RemoveObserver(bookmark_model_observer_.get()); - bookmark_model_ = nullptr; - bookmark_model_observer_.reset(); - - if (worker_) { - DisconnectSync(); - } + StopTrackingMetadata(); } void BookmarkModelTypeProcessor::StartTrackingMetadata( @@ -407,6 +426,16 @@ bookmark_model_->AddObserver(bookmark_model_observer_.get()); } +void BookmarkModelTypeProcessor::StopTrackingMetadata() { + DCHECK(bookmark_model_observer_); + + bookmark_model_->RemoveObserver(bookmark_model_observer_.get()); + bookmark_model_ = nullptr; + bookmark_model_observer_.reset(); + + DisconnectSync(); +} + void BookmarkModelTypeProcessor::GetAllNodesForDebugging( AllNodesCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/components/sync_bookmarks/bookmark_model_type_processor.h b/components/sync_bookmarks/bookmark_model_type_processor.h index f0a9ce58..d0030bd 100644 --- a/components/sync_bookmarks/bookmark_model_type_processor.h +++ b/components/sync_bookmarks/bookmark_model_type_processor.h
@@ -106,6 +106,7 @@ void StartTrackingMetadata( std::vector<NodeMetadataPair> nodes_metadata, std::unique_ptr<sync_pb::ModelTypeState> model_type_state); + void StopTrackingMetadata(); // Creates a DictionaryValue for local and remote debugging information about // |node| and appends it to |all_nodes|. It does the same for child nodes @@ -158,6 +159,8 @@ // engine. std::string cache_guid_; + syncer::ModelErrorHandler error_handler_; + std::unique_ptr<BookmarkModelObserverImpl> bookmark_model_observer_; base::WeakPtrFactory<BookmarkModelTypeProcessor> weak_ptr_factory_;
diff --git a/components/translate/core/browser/translate_infobar_delegate.cc b/components/translate/core/browser/translate_infobar_delegate.cc index 9b3d4c9..148300f5 100644 --- a/components/translate/core/browser/translate_infobar_delegate.cc +++ b/components/translate/core/browser/translate_infobar_delegate.cc
@@ -139,7 +139,7 @@ ui_delegate_.TranslationDeclined(true); } -bool TranslateInfoBarDelegate::IsTranslatableLanguageByPrefs() { +bool TranslateInfoBarDelegate::IsTranslatableLanguageByPrefs() const { TranslateClient* client = translate_manager_->translate_client(); std::unique_ptr<TranslatePrefs> translate_prefs(client->GetTranslatePrefs()); TranslateAcceptLanguages* accept_languages = @@ -157,7 +157,7 @@ } } -bool TranslateInfoBarDelegate::IsSiteBlacklisted() { +bool TranslateInfoBarDelegate::IsSiteBlacklisted() const { return ui_delegate_.IsSiteBlacklisted(); } @@ -170,7 +170,7 @@ } } -bool TranslateInfoBarDelegate::ShouldAlwaysTranslate() { +bool TranslateInfoBarDelegate::ShouldAlwaysTranslate() const { return ui_delegate_.ShouldAlwaysTranslate(); }
diff --git a/components/translate/core/browser/translate_infobar_delegate.h b/components/translate/core/browser/translate_infobar_delegate.h index a30bf284..0e6237d 100644 --- a/components/translate/core/browser/translate_infobar_delegate.h +++ b/components/translate/core/browser/translate_infobar_delegate.h
@@ -137,11 +137,11 @@ virtual void TranslationDeclined(); // Methods called by the Options menu delegate. - virtual bool IsTranslatableLanguageByPrefs(); + virtual bool IsTranslatableLanguageByPrefs() const; virtual void ToggleTranslatableLanguageByPrefs(); - virtual bool IsSiteBlacklisted(); + virtual bool IsSiteBlacklisted() const; virtual void ToggleSiteBlacklist(); - virtual bool ShouldAlwaysTranslate(); + virtual bool ShouldAlwaysTranslate() const; virtual void ToggleAlwaysTranslate(); // Methods called by the extra-buttons that can appear on the "before
diff --git a/components/translate/core/browser/translate_ui_delegate.cc b/components/translate/core/browser/translate_ui_delegate.cc index 7a13fa15..3812880 100644 --- a/components/translate/core/browser/translate_ui_delegate.cc +++ b/components/translate/core/browser/translate_ui_delegate.cc
@@ -265,7 +265,7 @@ } } -bool TranslateUIDelegate::IsLanguageBlocked() { +bool TranslateUIDelegate::IsLanguageBlocked() const { return prefs_->IsBlockedLanguage(GetOriginalLanguageCode()); } @@ -288,12 +288,12 @@ UMA_HISTOGRAM_BOOLEAN(kNeverTranslateLang, value); } -bool TranslateUIDelegate::IsSiteBlacklisted() { +bool TranslateUIDelegate::IsSiteBlacklisted() const { std::string host = GetPageHost(); return !host.empty() && prefs_->IsSiteBlacklisted(host); } -bool TranslateUIDelegate::CanBlacklistSite() { +bool TranslateUIDelegate::CanBlacklistSite() const { return !GetPageHost().empty(); } @@ -319,22 +319,22 @@ UMA_HISTOGRAM_BOOLEAN(kNeverTranslateSite, value); } -bool TranslateUIDelegate::ShouldAlwaysTranslate() { +bool TranslateUIDelegate::ShouldAlwaysTranslate() const { return prefs_->IsLanguagePairWhitelisted(GetOriginalLanguageCode(), GetTargetLanguageCode()); } -bool TranslateUIDelegate::ShouldAlwaysTranslateBeCheckedByDefault() { +bool TranslateUIDelegate::ShouldAlwaysTranslateBeCheckedByDefault() const { return ShouldAlwaysTranslate(); } -bool TranslateUIDelegate::ShouldShowAlwaysTranslateShortcut() { +bool TranslateUIDelegate::ShouldShowAlwaysTranslateShortcut() const { return !translate_driver_->IsIncognito() && prefs_->GetTranslationAcceptedCount(GetOriginalLanguageCode()) >= kAlwaysTranslateShortcutMinimumAccepts; } -bool TranslateUIDelegate::ShouldShowNeverTranslateShortcut() { +bool TranslateUIDelegate::ShouldShowNeverTranslateShortcut() const { return !translate_driver_->IsIncognito() && prefs_->GetTranslationDeniedCount(GetOriginalLanguageCode()) >= kNeverTranslateShortcutMinimumDenials; @@ -360,7 +360,7 @@ UMA_HISTOGRAM_BOOLEAN(kAlwaysTranslateLang, value); } -std::string TranslateUIDelegate::GetPageHost() { +std::string TranslateUIDelegate::GetPageHost() const { if (!translate_driver_->HasCurrentPage()) return std::string(); return translate_driver_->GetLastCommittedURL().HostNoBrackets();
diff --git a/components/translate/core/browser/translate_ui_delegate.h b/components/translate/core/browser/translate_ui_delegate.h index e7ebff5..a58bdf7 100644 --- a/components/translate/core/browser/translate_ui_delegate.h +++ b/components/translate/core/browser/translate_ui_delegate.h
@@ -100,16 +100,16 @@ void TranslationDeclined(bool explicitly_closed); // Returns true if the current language is blocked. - bool IsLanguageBlocked(); + bool IsLanguageBlocked() const; // Sets the value if the current language is blocked. void SetLanguageBlocked(bool value); // Returns true if the current webpage is blacklisted. - bool IsSiteBlacklisted(); + bool IsSiteBlacklisted() const; // Returns true if the site of the current webpage can be blacklisted. - bool CanBlacklistSite(); + bool CanBlacklistSite() const; // Sets the blacklisted state for the host of the current page. If // value is true, the current host will be blacklisted and translations @@ -118,29 +118,29 @@ // Returns true if the webpage in the current original language should be // translated into the current target language automatically. - bool ShouldAlwaysTranslate(); + bool ShouldAlwaysTranslate() const; // Sets the value if the webpage in the current original language should be // translated into the current target language automatically. void SetAlwaysTranslate(bool value); // Returns true if the Always Translate checkbox should be checked by default. - bool ShouldAlwaysTranslateBeCheckedByDefault(); + bool ShouldAlwaysTranslateBeCheckedByDefault() const; // Returns true if the UI should offer the user a shortcut to always translate // the language, when we think the user wants that functionality. - bool ShouldShowAlwaysTranslateShortcut(); + bool ShouldShowAlwaysTranslateShortcut() const; // Returns true if the UI should offer the user a shortcut to never translate // the language, when we think the user wants that functionality. - bool ShouldShowNeverTranslateShortcut(); + bool ShouldShowNeverTranslateShortcut() const; private: FRIEND_TEST_ALL_PREFIXES(TranslateUIDelegateTest, GetPageHost); // Gets the host of the page being translated, or an empty string if no URL is // associated with the current page. - std::string GetPageHost(); + std::string GetPageHost() const; TranslateDriver* translate_driver_; base::WeakPtr<TranslateManager> translate_manager_;
diff --git a/components/ui_devtools/devtools.gni b/components/ui_devtools/devtools.gni index e74e697..02212083 100644 --- a/components/ui_devtools/devtools.gni +++ b/components/ui_devtools/devtools.gni
@@ -3,7 +3,7 @@ # found in the LICENSE file. declare_args() { - # Indicates if the Viz Devtools server is enabled. This is disabled on - # official Android and iOS builds to reduce binary size. - use_viz_devtools = !((is_android || is_ios) && is_official_build) + # Indicates if the Viz Devtools server is enabled. This is disabled on iOS, + # and on official Android builds to reduce binary size. + use_viz_devtools = !(is_ios || (is_android && is_official_build)) }
diff --git a/components/ui_devtools/ui_devtools_unittest_utils.cc b/components/ui_devtools/ui_devtools_unittest_utils.cc index ba655e24..462cc9f2 100644 --- a/components/ui_devtools/ui_devtools_unittest_utils.cc +++ b/components/ui_devtools/ui_devtools_unittest_utils.cc
@@ -31,6 +31,7 @@ void FakeFrontendChannel::sendProtocolNotification( std::unique_ptr<protocol::Serializable> message) { + EXPECT_TRUE(allow_notifications_); protocol_notification_messages_.push_back(message->serialize()); }
diff --git a/components/ui_devtools/ui_devtools_unittest_utils.h b/components/ui_devtools/ui_devtools_unittest_utils.h index 544e38ba..d2906157 100644 --- a/components/ui_devtools/ui_devtools_unittest_utils.h +++ b/components/ui_devtools/ui_devtools_unittest_utils.h
@@ -20,6 +20,10 @@ int CountProtocolNotificationMessage(const std::string& message); + void SetAllowNotifications(bool allow_notifications) { + allow_notifications_ = allow_notifications; + } + // FrontendChannel: void sendProtocolResponse( int callId, @@ -33,6 +37,7 @@ private: std::vector<std::string> protocol_notification_messages_; + bool allow_notifications_ = true; DISALLOW_COPY_AND_ASSIGN(FakeFrontendChannel); };
diff --git a/components/ui_devtools/viz_views/BUILD.gn b/components/ui_devtools/viz_views/BUILD.gn index 8bc15045..e58f3ff 100644 --- a/components/ui_devtools/viz_views/BUILD.gn +++ b/components/ui_devtools/viz_views/BUILD.gn
@@ -21,3 +21,22 @@ "//components/viz/service", ] } + +source_set("unit_tests") { + testonly = true + + sources = [ + "viz_devtools_unittest.cc", + ] + + deps = [ + ":viz_views", + "//components/ui_devtools", + "//components/ui_devtools:test_support", + "//components/viz/service", + "//components/viz/test:test_support", + "//testing/gtest", + ] + + configs += [ "//build/config:precompiled_headers" ] +}
diff --git a/components/ui_devtools/viz_views/DEPS b/components/ui_devtools/viz_views/DEPS index 09a7019..45242826 100644 --- a/components/ui_devtools/viz_views/DEPS +++ b/components/ui_devtools/viz_views/DEPS
@@ -1,4 +1,5 @@ include_rules = [ "+components/viz/common", "+components/viz/service", + "+components/viz/test", ]
diff --git a/components/ui_devtools/viz_views/dom_agent_viz.cc b/components/ui_devtools/viz_views/dom_agent_viz.cc index 168e6cf..4a5c59a 100644 --- a/components/ui_devtools/viz_views/dom_agent_viz.cc +++ b/components/ui_devtools/viz_views/dom_agent_viz.cc
@@ -361,7 +361,10 @@ // root surface, and then delete the node we were asked for. UIElement* new_parent = (element->type() == SURFACE ? GetRootSurfaceElement() : element_root()); - for (auto* child : element->children()) + // Make a copy of the list of children, so that it isn't affected when + // elements are moved. + std::vector<UIElement*> children(element->children()); + for (auto* child : children) Reparent(new_parent, child); element->parent()->RemoveChild(element); @@ -369,6 +372,9 @@ } void DOMAgentViz::Reparent(UIElement* new_parent, UIElement* child) { + if (new_parent == child->parent()) + return; + DestroySubtree(child); // This removes the child element from the Node map. It has to be added with
diff --git a/components/ui_devtools/viz_views/dom_agent_viz.h b/components/ui_devtools/viz_views/dom_agent_viz.h index 762ca04c..8cf00b16 100644 --- a/components/ui_devtools/viz_views/dom_agent_viz.h +++ b/components/ui_devtools/viz_views/dom_agent_viz.h
@@ -62,6 +62,10 @@ const viz::FrameSinkId& parent_frame_sink_id, const viz::FrameSinkId& child_frame_sink_id) override; + // DOM::Backend: + protocol::Response enable() override; + protocol::Response disable() override; + SurfaceElement* GetRootSurfaceElement(); private: @@ -73,10 +77,6 @@ UIElement* parent_element, const viz::SurfaceId& parent_id); - // DOM::Backend: - protocol::Response enable() override; - protocol::Response disable() override; - // DOMAgent: std::vector<UIElement*> CreateChildrenForRoot() override; std::unique_ptr<protocol::DOM::Node> BuildTreeForUIElement(
diff --git a/components/ui_devtools/viz_views/viz_devtools_unittest.cc b/components/ui_devtools/viz_views/viz_devtools_unittest.cc new file mode 100644 index 0000000..c51e7777 --- /dev/null +++ b/components/ui_devtools/viz_views/viz_devtools_unittest.cc
@@ -0,0 +1,468 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/ui_devtools/css_agent.h" +#include "components/ui_devtools/ui_devtools_unittest_utils.h" +#include "components/ui_devtools/ui_element.h" +#include "components/ui_devtools/viz_views/dom_agent_viz.h" +#include "components/ui_devtools/viz_views/frame_sink_element.h" +#include "components/ui_devtools/viz_views/overlay_agent_viz.h" +#include "components/ui_devtools/viz_views/surface_element.h" +#include "components/viz/common/surfaces/frame_sink_id.h" +#include "components/viz/common/surfaces/surface_id.h" +#include "components/viz/common/surfaces/surface_info.h" +#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" +#include "components/viz/service/surfaces/surface_manager.h" +#include "components/viz/service/surfaces/surface_reference.h" +#include "components/viz/test/compositor_frame_helpers.h" +#include "components/viz/test/test_shared_bitmap_manager.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/platform_test.h" + +using namespace ui_devtools::protocol; + +namespace ui_devtools { +namespace { + +constexpr viz::FrameSinkId kFrameSink1(1, 0); +constexpr viz::FrameSinkId kFrameSink2(2, 0); +constexpr viz::FrameSinkId kFrameSink3(3, 0); + +bool HasAttributeWithValue(const std::string& attribute, + const std::string& value, + DOM::Node* node) { + if (!node->hasAttributes()) + return false; + Array<std::string>* attributes = node->getAttributes(nullptr); + for (size_t i = 0; i < attributes->length() - 1; i += 2) { + if (attributes->get(i) == attribute) { + return attributes->get(i + 1) == value; + } + } + return false; +} + +// Recursively search for a node with an attribute and a matching value. +DOM::Node* FindNodeByAttribute(const std::string& attribute, + const std::string& value, + DOM::Node* root) { + if (HasAttributeWithValue(attribute, value, root)) + return root; + + Array<DOM::Node>* children = root->getChildren(nullptr); + for (size_t i = 0; i < children->length(); ++i) { + DOM::Node* node = FindNodeByAttribute(attribute, value, children->get(i)); + if (node) + return node; + } + return nullptr; +} + +DOM::Node* FindFrameSinkNode(const viz::FrameSinkId& frame_sink_id, + DOM::Node* root) { + return FindNodeByAttribute("FrameSinkId", frame_sink_id.ToString(), root); +} + +DOM::Node* FindSurfaceNode(const viz::SurfaceId& surface_id, DOM::Node* root) { + return FindNodeByAttribute("SurfaceId", surface_id.ToString(), root); +} + +} // namespace + +class VizDevToolsTest : public PlatformTest { + public: + VizDevToolsTest() = default; + ~VizDevToolsTest() override = default; + + void SetUp() override { + frontend_channel_ = std::make_unique<FakeFrontendChannel>(); + uber_dispatcher_ = + std::make_unique<UberDispatcher>(frontend_channel_.get()); + manager_ = + std::make_unique<viz::FrameSinkManagerImpl>(&shared_bitmap_manager_); + dom_agent_ = std::make_unique<DOMAgentViz>(frame_sink_manager()); + dom_agent_->Init(uber_dispatcher_.get()); + css_agent_ = std::make_unique<CSSAgent>(dom_agent_.get()); + css_agent_->Init(uber_dispatcher_.get()); + css_agent_->enable(); + overlay_agent_ = std::make_unique<OverlayAgentViz>(dom_agent_.get()); + overlay_agent_->Init(uber_dispatcher_.get()); + overlay_agent_->enable(); + } + + void TearDown() override { + root_.reset(); + dom_agent_->disable(); + supports_.clear(); + overlay_agent_.reset(); + css_agent_.reset(); + dom_agent_.reset(); + manager_.reset(); + uber_dispatcher_.reset(); + frontend_channel_.reset(); + } + + void ExpectChildNodeInserted(int parent_id, + int prev_sibling_id, + int expected_count = 1) { + int count = frontend_channel()->CountProtocolNotificationMessageStartsWith( + base::StringPrintf("{\"method\":\"DOM.childNodeInserted\",\"params\":{" + "\"parentNodeId\":%d,\"previousNodeId\":%d,", + parent_id, prev_sibling_id)); + EXPECT_EQ(expected_count, count); + } + + void ExpectChildNodeRemoved(int parent_id, + int node_id, + int expected_count = 1) { + int count = frontend_channel()->CountProtocolNotificationMessage( + base::StringPrintf("{\"method\":\"DOM.childNodeRemoved\",\"params\":{" + "\"parentNodeId\":%d,\"nodeId\":%d}}", + parent_id, node_id)); + EXPECT_EQ(expected_count, count); + } + + void RegisterFrameSinkId(const viz::FrameSinkId& frame_sink_id) { + frame_sink_manager()->RegisterFrameSinkId(frame_sink_id, true); + } + + void InvalidateFrameSinkId(const viz::FrameSinkId& frame_sink_id) { + frame_sink_manager()->InvalidateFrameSinkId(frame_sink_id); + } + + void AddSurfaceReference(const viz::SurfaceId& parent_id, + const viz::SurfaceId& child_id) { + surface_manager()->AddSurfaceReferences( + {viz::SurfaceReference(parent_id, child_id)}); + } + + void RemoveSurfaceReference(const viz::SurfaceId& parent_id, + const viz::SurfaceId& child_id) { + surface_manager()->RemoveSurfaceReferences( + {viz::SurfaceReference(parent_id, child_id)}); + } + + // Creates a new Surface with the provided |frame_sink_id| and |parent_id|. + // Will register and create a CompositorFrameSinkSupport for |frame_sink_id| + // if necessary. + viz::SurfaceId CreateFrameSinkAndSurface( + const viz::FrameSinkId& frame_sink_id, + uint32_t parent_id) { + viz::LocalSurfaceId local_surface_id( + parent_id, base::UnguessableToken::Deserialize(0, 1u)); + // Ensure that a CompositorFrameSinkSupport exists for this frame sink. + auto& support = supports_[frame_sink_id]; + if (!support) { + frame_sink_manager()->RegisterFrameSinkId(frame_sink_id, + /*report_activation=*/true); + support = std::make_unique<viz::CompositorFrameSinkSupport>( + /*client=*/nullptr, frame_sink_manager(), frame_sink_id, + /*is_root=*/false, /*needs_sync_points=*/true); + } + viz::CompositorFrame frame = viz::MakeDefaultCompositorFrame(); + gfx::Size size = frame.size_in_pixels(); + support->SubmitCompositorFrame(local_surface_id, std::move(frame)); + // The surface isn't added to viz devtools yet, OnFirstSurfaceActivation + // needs to be called. + viz::SurfaceId surface_id(frame_sink_id, local_surface_id); + viz::SurfaceInfo surface_info(surface_id, 1.f, size); + surface_manager()->FirstSurfaceActivation(surface_info); + return surface_id; + } + + // Destroy Surface with |surface_id|, and garbage collect it. + void DestroySurface(const viz::SurfaceId& surface_id) { + auto support_iter = supports_.find(surface_id.frame_sink_id()); + EXPECT_NE(support_iter, supports_.end()); + support_iter->second->EvictSurface(surface_id.local_surface_id()); + surface_manager()->GarbageCollectSurfaces(); + } + + // Build the document tree, and begin listening for updates. The document + // stored in |root_| is a snapshot and doesn't change when updates are sent + // to |frontend_channel_|. + void BuildDocument() { + dom_agent()->disable(); + dom_agent()->getDocument(&root_); + dom_agent()->enable(); + } + + DOMAgentViz* dom_agent() { return dom_agent_.get(); } + FakeFrontendChannel* frontend_channel() { return frontend_channel_.get(); } + viz::FrameSinkManagerImpl* frame_sink_manager() { return manager_.get(); } + viz::SurfaceManager* surface_manager() { return manager_->surface_manager(); } + DOM::Node* root() { return root_.get(); } + + private: + viz::TestSharedBitmapManager shared_bitmap_manager_; + std::unique_ptr<FakeFrontendChannel> frontend_channel_; + std::unique_ptr<UberDispatcher> uber_dispatcher_; + std::unique_ptr<viz::FrameSinkManagerImpl> manager_; + std::unique_ptr<DOMAgentViz> dom_agent_; + std::unique_ptr<CSSAgent> css_agent_; + std::unique_ptr<OverlayAgentViz> overlay_agent_; + + std::unique_ptr<DOM::Node> root_; + base::flat_map<viz::FrameSinkId, + std::unique_ptr<viz::CompositorFrameSinkSupport>> + supports_; + + DISALLOW_COPY_AND_ASSIGN(VizDevToolsTest); +}; + +// Verify that registering a FrameSinkId creates a node. +TEST_F(VizDevToolsTest, FrameSinkRegistered) { + BuildDocument(); + + RegisterFrameSinkId(kFrameSink1); + + ExpectChildNodeInserted(dom_agent()->element_root()->node_id(), 0); +} + +// Verify that invalidating a FrameSinkId removes a node. +TEST_F(VizDevToolsTest, FrameSinkInvalidated) { + RegisterFrameSinkId(kFrameSink1); + + BuildDocument(); + + InvalidateFrameSinkId(kFrameSink1); + + DOM::Node* frame_sink_node = FindFrameSinkNode(kFrameSink1, root()); + ExpectChildNodeRemoved(dom_agent()->element_root()->node_id(), + frame_sink_node->getNodeId()); +} + +// Verify that registering a FrameSink hierarchy moves a node to its new parent. +TEST_F(VizDevToolsTest, FrameSinkHierarchyRegistered) { + RegisterFrameSinkId(kFrameSink1); + RegisterFrameSinkId(kFrameSink2); + + BuildDocument(); + + frame_sink_manager()->RegisterFrameSinkHierarchy(kFrameSink1, kFrameSink2); + + DOM::Node* parent_node = FindFrameSinkNode(kFrameSink1, root()); + DOM::Node* child_node = FindFrameSinkNode(kFrameSink2, root()); + ExpectChildNodeRemoved(dom_agent()->element_root()->node_id(), + child_node->getNodeId()); + ExpectChildNodeInserted(parent_node->getNodeId(), 0); +} + +// Verify that unregistering a FrameSink hierarchy moves a node to the root +// element. +TEST_F(VizDevToolsTest, FrameSinkHierarchyUnregistered) { + RegisterFrameSinkId(kFrameSink1); + RegisterFrameSinkId(kFrameSink2); + frame_sink_manager()->RegisterFrameSinkHierarchy(kFrameSink1, kFrameSink2); + + BuildDocument(); + + frame_sink_manager()->UnregisterFrameSinkHierarchy(kFrameSink1, kFrameSink2); + + DOM::Node* parent_node = FindFrameSinkNode(kFrameSink1, root()); + DOM::Node* child_node = FindFrameSinkNode(kFrameSink2, parent_node); + ExpectChildNodeRemoved(parent_node->getNodeId(), child_node->getNodeId()); + ExpectChildNodeInserted(dom_agent()->element_root()->node_id(), 0); +} + +// Verify that the initial tree at viz devtools startup is correct, including an +// existing hierarchy, and a detached frame sink with no parent. +TEST_F(VizDevToolsTest, InitialFrameSinkHierarchy) { + RegisterFrameSinkId(kFrameSink1); + RegisterFrameSinkId(kFrameSink2); + RegisterFrameSinkId(kFrameSink3); + frame_sink_manager()->RegisterFrameSinkHierarchy(kFrameSink1, kFrameSink2); + + BuildDocument(); + + DOM::Node* node1 = FindFrameSinkNode(kFrameSink1, root()); + DOM::Node* node2 = FindFrameSinkNode(kFrameSink2, node1); + DOM::Node* node3 = FindFrameSinkNode(kFrameSink3, root()); + + // The first and third frame sinks are children of the root element. + EXPECT_EQ(node1, root()->getChildren(nullptr)->get(0)); + EXPECT_EQ(node2, node1->getChildren(nullptr)->get(0)); + EXPECT_EQ(node3, root()->getChildren(nullptr)->get(1)); +} + +// Verify that creating a surface and adding a reference to the root surface +// creates a node attached to the root surface node. +TEST_F(VizDevToolsTest, SurfaceCreated) { + BuildDocument(); + + viz::SurfaceId id1 = CreateFrameSinkAndSurface(kFrameSink1, 1); + AddSurfaceReference(surface_manager()->GetRootSurfaceId(), id1); + + ExpectChildNodeInserted(dom_agent()->GetRootSurfaceElement()->node_id(), 0); +} + +// Verify that destroying a surface removes a node from the root surface node. +TEST_F(VizDevToolsTest, SurfaceDestroyed) { + viz::SurfaceId id1 = CreateFrameSinkAndSurface(kFrameSink1, 1); + AddSurfaceReference(surface_manager()->GetRootSurfaceId(), id1); + + BuildDocument(); + + RemoveSurfaceReference(surface_manager()->GetRootSurfaceId(), id1); + DestroySurface(id1); + + DOM::Node* surface_node = FindSurfaceNode(id1, root()); + ExpectChildNodeRemoved(dom_agent()->GetRootSurfaceElement()->node_id(), + surface_node->getNodeId()); +} + +// Verify that adding a surface reference moves a node from the root surface to +// the new parent. +TEST_F(VizDevToolsTest, SurfaceReferenceAdded) { + viz::SurfaceId id1 = CreateFrameSinkAndSurface(kFrameSink1, 1); + viz::SurfaceId id2 = CreateFrameSinkAndSurface(kFrameSink2, 1); + AddSurfaceReference(surface_manager()->GetRootSurfaceId(), id1); + AddSurfaceReference(surface_manager()->GetRootSurfaceId(), id2); + + BuildDocument(); + + RemoveSurfaceReference(surface_manager()->GetRootSurfaceId(), id2); + AddSurfaceReference(id1, id2); + + DOM::Node* parent_node = FindSurfaceNode(id1, root()); + DOM::Node* child_node = FindSurfaceNode(id2, root()); + ExpectChildNodeRemoved(dom_agent()->GetRootSurfaceElement()->node_id(), + child_node->getNodeId()); + ExpectChildNodeInserted(parent_node->getNodeId(), 0); +} + +// Verify that adding a surface reference moves a node from its parent to the +// root surface. +TEST_F(VizDevToolsTest, SurfaceReferenceRemoved) { + viz::SurfaceId id1 = CreateFrameSinkAndSurface(kFrameSink1, 1); + viz::SurfaceId id2 = CreateFrameSinkAndSurface(kFrameSink2, 1); + AddSurfaceReference(surface_manager()->GetRootSurfaceId(), id1); + AddSurfaceReference(id1, id2); + + BuildDocument(); + + RemoveSurfaceReference(id1, id2); + + DOM::Node* parent_node = FindSurfaceNode(id1, root()); + DOM::Node* child_node = FindSurfaceNode(id2, parent_node); + ExpectChildNodeRemoved(parent_node->getNodeId(), child_node->getNodeId()); + ExpectChildNodeInserted(dom_agent()->GetRootSurfaceElement()->node_id(), 0); +} + +// Verify that a hierarchy of surfaces can be destroyed and cleaned up properly. +TEST_F(VizDevToolsTest, SurfaceHierarchyCleanup) { + viz::SurfaceId parent_surface_id = CreateFrameSinkAndSurface(kFrameSink1, 1); + AddSurfaceReference(surface_manager()->GetRootSurfaceId(), parent_surface_id); + + std::vector<viz::FrameSinkId> child_frame_sink_ids = { + viz::FrameSinkId(5, 0), viz::FrameSinkId(6, 0), viz::FrameSinkId(7, 0), + viz::FrameSinkId(8, 0), viz::FrameSinkId(9, 0), + }; + + std::vector<viz::SurfaceId> child_surface_ids; + for (auto& frame_sink_id : child_frame_sink_ids) { + viz::SurfaceId surface_id = CreateFrameSinkAndSurface(frame_sink_id, 1); + AddSurfaceReference(parent_surface_id, surface_id); + child_surface_ids.push_back(surface_id); + } + + BuildDocument(); + + RemoveSurfaceReference(surface_manager()->GetRootSurfaceId(), + parent_surface_id); + DestroySurface(parent_surface_id); + + // It is safe to access |parent_node| after the surface was just destroyed + // because updates to the frontend are not applied to |root_|. + DOM::Node* parent_node = FindSurfaceNode(parent_surface_id, root()); + for (auto& surface_id : child_surface_ids) { + // Each child surface should have been moved to the root surface when the + // parent surface was removed, but it shouldn't be discarded yet. + DOM::Node* child_node = FindSurfaceNode(surface_id, parent_node); + ExpectChildNodeRemoved(parent_node->getNodeId(), child_node->getNodeId()); + ExpectChildNodeRemoved(dom_agent()->GetRootSurfaceElement()->node_id(), + child_node->getNodeId(), /*count=*/0); + + // Evict and garbage collect, this should remove the element. + DestroySurface(surface_id); + ExpectChildNodeRemoved(dom_agent()->GetRootSurfaceElement()->node_id(), + child_node->getNodeId(), /*count=*/1); + } +} + +// Verify that a surface with multiple references is only a child of its most +// recent referrer. +// TODO(sgilhuly): This test follows the current behaviour of surfaces with +// multiple references, and should be changed if support for nodes to have +// multiple parents is added. +TEST_F(VizDevToolsTest, MultipleSurfaceReferences) { + viz::SurfaceId parent_id_1 = CreateFrameSinkAndSurface(kFrameSink1, 1); + viz::SurfaceId parent_id_2 = CreateFrameSinkAndSurface(kFrameSink2, 1); + viz::SurfaceId child_id = CreateFrameSinkAndSurface(kFrameSink3, 1); + AddSurfaceReference(surface_manager()->GetRootSurfaceId(), parent_id_1); + AddSurfaceReference(surface_manager()->GetRootSurfaceId(), parent_id_2); + AddSurfaceReference(surface_manager()->GetRootSurfaceId(), child_id); + + BuildDocument(); + + DOM::Node* parent_node_1 = FindSurfaceNode(parent_id_1, root()); + DOM::Node* parent_node_2 = FindSurfaceNode(parent_id_2, root()); + DOM::Node* child_node = FindSurfaceNode(child_id, root()); + + // Attach to the first parent, while still being referenced by the root + // surface. This should move the child node. + AddSurfaceReference(parent_id_1, child_id); + ExpectChildNodeInserted(parent_node_1->getNodeId(), 0); + ExpectChildNodeRemoved(dom_agent()->GetRootSurfaceElement()->node_id(), + child_node->getNodeId()); + + // Attach to the second parent, while still being referenced by the first + // parent. This should move the child node. + AddSurfaceReference(parent_id_2, child_id); + ExpectChildNodeInserted(parent_node_2->getNodeId(), 0); + ExpectChildNodeRemoved(parent_node_1->getNodeId(), child_node->getNodeId()); + + // Remove the references to the root surface, and the first parent. This + // should do nothing. + frontend_channel()->SetAllowNotifications(false); + RemoveSurfaceReference(surface_manager()->GetRootSurfaceId(), child_id); + RemoveSurfaceReference(parent_id_1, child_id); + frontend_channel()->SetAllowNotifications(true); + + // Remove the reference to the second parent. This should move the child node + // to the root surface. + RemoveSurfaceReference(parent_id_2, child_id); + ExpectChildNodeInserted(dom_agent()->GetRootSurfaceElement()->node_id(), 0); + ExpectChildNodeRemoved(parent_node_2->getNodeId(), child_node->getNodeId()); +} + +// Verify that a surface reference can be added if there is no node for the +// parent. +TEST_F(VizDevToolsTest, SurfaceReferenceAddedBeforeParentActivation) { + viz::SurfaceId parent_id = CreateFrameSinkAndSurface(kFrameSink1, 1); + viz::SurfaceId child_id = CreateFrameSinkAndSurface(kFrameSink2, 1); + + BuildDocument(); + + AddSurfaceReference(parent_id, child_id); + + ExpectChildNodeInserted(dom_agent()->GetRootSurfaceElement()->node_id(), 0); +} + +// Verify that a surface reference can be added if there is no node for the +// child. +TEST_F(VizDevToolsTest, SurfaceReferenceAddedBeforeChildActivation) { + viz::SurfaceId parent_id = CreateFrameSinkAndSurface(kFrameSink1, 1); + viz::SurfaceId child_id = CreateFrameSinkAndSurface(kFrameSink2, 1); + AddSurfaceReference(surface_manager()->GetRootSurfaceId(), parent_id); + + BuildDocument(); + + AddSurfaceReference(parent_id, child_id); + + DOM::Node* parent_node = FindSurfaceNode(parent_id, root()); + ExpectChildNodeInserted(parent_node->getNodeId(), 0); +} + +} // namespace ui_devtools
diff --git a/components/version_ui/resources/about_version.html b/components/version_ui/resources/about_version.html index 68b9659..a6ddaff 100644 --- a/components/version_ui/resources/about_version.html +++ b/components/version_ui/resources/about_version.html
@@ -69,6 +69,9 @@ <if expr="is_android"> <span>$i18n{os_version}</span> </if> +<if expr="is_win"> + <span id="os_version"></span> +</if> </td> </tr> </if>
diff --git a/components/viz/common/features.cc b/components/viz/common/features.cc index 6fd15e5..5b878377 100644 --- a/components/viz/common/features.cc +++ b/components/viz/common/features.cc
@@ -26,7 +26,7 @@ // Enables running the display compositor as part of the viz service in the GPU // process. This is also referred to as out-of-process display compositor // (OOP-D). -#if defined(OS_CHROMEOS) || defined(OS_ANDROID) +#if defined(OS_CHROMEOS) || defined(OS_ANDROID) || defined(OS_FUCHSIA) const base::Feature kVizDisplayCompositor{"VizDisplayCompositor", base::FEATURE_DISABLED_BY_DEFAULT}; #else
diff --git a/components/viz/test/test_context_provider.cc b/components/viz/test/test_context_provider.cc index de2b0d4..a9c796f5 100644 --- a/components/viz/test/test_context_provider.cc +++ b/components/viz/test/test_context_provider.cc
@@ -22,7 +22,6 @@ #include "gpu/skia_bindings/grcontext_for_gles2_interface.h" #include "third_party/skia/include/gpu/GrContext.h" #include "third_party/skia/include/gpu/gl/GrGLInterface.h" -#include "ui/gfx/gpu_memory_buffer.h" namespace viz { @@ -123,7 +122,6 @@ uint32_t usage) { auto mailbox = gpu::Mailbox::Generate(); shared_images_.insert(mailbox); - most_recent_size_ = size; return mailbox; } @@ -145,7 +143,6 @@ uint32_t usage) { auto mailbox = gpu::Mailbox::Generate(); shared_images_.insert(mailbox); - most_recent_size_ = gpu_memory_buffer->GetSize(); return mailbox; } @@ -166,11 +163,6 @@ gpu::CommandBufferId(), ++release_id_); } -bool TestSharedImageInterface::CheckSharedImageExists( - const gpu::Mailbox& mailbox) const { - return shared_images_.contains(mailbox); -} - // static scoped_refptr<TestContextProvider> TestContextProvider::Create( std::string additional_extensions) {
diff --git a/components/viz/test/test_context_provider.h b/components/viz/test/test_context_provider.h index 8e36387..ab0af20f 100644 --- a/components/viz/test/test_context_provider.h +++ b/components/viz/test/test_context_provider.h
@@ -23,7 +23,6 @@ #include "gpu/command_buffer/client/gles2_interface_stub.h" #include "gpu/command_buffer/client/shared_image_interface.h" #include "gpu/config/gpu_feature_info.h" -#include "testing/gmock/include/gmock/gmock.h" #include "third_party/skia/include/core/SkRefCnt.h" namespace skia_bindings { @@ -64,12 +63,9 @@ gpu::SyncToken GenUnverifiedSyncToken() override; size_t shared_image_count() const { return shared_images_.size(); } - const gfx::Size& MostRecentSize() const { return most_recent_size_; } - bool CheckSharedImageExists(const gpu::Mailbox& mailbox) const; private: uint64_t release_id_ = 0; - gfx::Size most_recent_size_; base::flat_set<gpu::Mailbox> shared_images_; };
diff --git a/components/viz/test/test_gpu_memory_buffer_manager.cc b/components/viz/test/test_gpu_memory_buffer_manager.cc index b8baf92..8b2a789 100644 --- a/components/viz/test/test_gpu_memory_buffer_manager.cc +++ b/components/viz/test/test_gpu_memory_buffer_manager.cc
@@ -178,8 +178,6 @@ gfx::BufferFormat format, gfx::BufferUsage usage, gpu::SurfaceHandle surface_handle) { - if (fail_on_create_) - return nullptr; const size_t buffer_size = gfx::BufferSizeForBufferFormat(size, format); base::UnsafeSharedMemoryRegion shared_memory_region = base::UnsafeSharedMemoryRegion::Create(buffer_size);
diff --git a/components/viz/test/test_gpu_memory_buffer_manager.h b/components/viz/test/test_gpu_memory_buffer_manager.h index 180574de..2fad0d7 100644 --- a/components/viz/test/test_gpu_memory_buffer_manager.h +++ b/components/viz/test/test_gpu_memory_buffer_manager.h
@@ -24,10 +24,6 @@ void OnGpuMemoryBufferDestroyed(gfx::GpuMemoryBufferId gpu_memory_buffer_id); - void SetFailOnCreate(bool fail_on_create) { - fail_on_create_ = fail_on_create; - } - // Overridden from gpu::GpuMemoryBufferManager: std::unique_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer( const gfx::Size& size, @@ -52,8 +48,6 @@ int last_client_id_ = 5000; std::map<int, TestGpuMemoryBufferManager*> clients_; - bool fail_on_create_ = false; - DISALLOW_COPY_AND_ASSIGN(TestGpuMemoryBufferManager); };
diff --git a/content/browser/accessibility/accessibility_tree_formatter_blink.cc b/content/browser/accessibility/accessibility_tree_formatter_blink.cc index 022b08ab..05f47a4 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_blink.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_blink.cc
@@ -19,6 +19,7 @@ #include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_node_data.h" #include "ui/accessibility/platform/ax_platform_node_delegate.h" +#include "ui/accessibility/platform/compute_attributes.h" #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/transform.h" @@ -48,81 +49,6 @@ return base::nullopt; } -base::Optional<int32_t> GetCellAttribute( - const ui::AXPlatformNodeDelegate* delegate, - ax::mojom::IntAttribute attribute) { - switch (attribute) { - case ax::mojom::IntAttribute::kAriaCellColumnIndex: - return delegate->GetTableCellAriaColIndex(); - case ax::mojom::IntAttribute::kAriaCellRowIndex: - return delegate->GetTableCellAriaRowIndex(); - case ax::mojom::IntAttribute::kTableCellColumnIndex: - return delegate->GetTableCellColIndex(); - case ax::mojom::IntAttribute::kTableCellRowIndex: - return delegate->GetTableCellRowIndex(); - case ax::mojom::IntAttribute::kTableCellColumnSpan: - return delegate->GetTableCellColSpan(); - case ax::mojom::IntAttribute::kTableCellRowSpan: - return delegate->GetTableCellRowSpan(); - default: - return base::nullopt; - } -} - -base::Optional<int32_t> GetRowAttribute( - const ui::AXPlatformNodeDelegate* delegate, - ax::mojom::IntAttribute attribute) { - if (attribute == ax::mojom::IntAttribute::kTableRowIndex) { - return delegate->GetTableRowRowIndex(); - } - return base::nullopt; -} - -base::Optional<int32_t> GetTableAttribute( - const ui::AXPlatformNodeDelegate* delegate, - ax::mojom::IntAttribute attribute) { - switch (attribute) { - case ax::mojom::IntAttribute::kTableColumnCount: - return delegate->GetTableColCount(); - case ax::mojom::IntAttribute::kTableRowCount: - return delegate->GetTableRowCount(); - case ax::mojom::IntAttribute::kAriaColumnCount: - return delegate->GetTableAriaColCount(); - case ax::mojom::IntAttribute::kAriaRowCount: - return delegate->GetTableAriaRowCount(); - default: - return base::nullopt; - } -} - -base::Optional<int32_t> GetFromData(const ui::AXPlatformNodeDelegate* delegate, - ax::mojom::IntAttribute attribute) { - int32_t value; - if (delegate->GetData().GetIntAttribute(attribute, &value)) { - return value; - } - return base::nullopt; -} - -// Compute the attribute value instead of returning the "raw" attribute value -// for those attributes that have computation methods. -base::Optional<int32_t> GetIntAttribute( - const ui::AXPlatformNodeDelegate* delegate, - ax::mojom::IntAttribute attribute) { - base::Optional<int32_t> maybe_value = base::nullopt; - if (delegate->IsTableCellOrHeader()) - maybe_value = GetCellAttribute(delegate, attribute); - else if (delegate->IsTableRow()) - maybe_value = GetRowAttribute(delegate, attribute); - else if (delegate->IsTable()) - maybe_value = GetTableAttribute(delegate, attribute); - - if (!maybe_value.has_value()) { - return GetFromData(delegate, attribute); - } - return maybe_value; -} - std::string IntAttrToString(const BrowserAccessibility& node, ax::mojom::IntAttribute attr, int32_t value) { @@ -292,7 +218,7 @@ attr_index <= static_cast<int32_t>(ax::mojom::IntAttribute::kMaxValue); ++attr_index) { auto attr = static_cast<ax::mojom::IntAttribute>(attr_index); - auto maybe_value = GetIntAttribute(&node, attr); + auto maybe_value = ui::ComputeAttribute(&node, attr); if (maybe_value.has_value()) { dict->SetString(ui::ToString(attr), IntAttrToString(node, attr, maybe_value.value()));
diff --git a/content/browser/background_fetch/background_fetch_context.cc b/content/browser/background_fetch/background_fetch_context.cc index f72a8d1..f45fed77 100644 --- a/content/browser/background_fetch/background_fetch_context.cc +++ b/content/browser/background_fetch/background_fetch_context.cc
@@ -250,10 +250,12 @@ data_manager_->MatchRequests( registration_id, std::move(match_params), base::BindOnce(&BackgroundFetchContext::DidGetMatchingRequests, - weak_factory_.GetWeakPtr(), std::move(callback))); + weak_factory_.GetWeakPtr(), registration_id.unique_id(), + std::move(callback))); } void BackgroundFetchContext::DidGetMatchingRequests( + const std::string& unique_id, blink::mojom::BackgroundFetchService::MatchRequestsCallback callback, blink::mojom::BackgroundFetchError error, std::vector<blink::mojom::BackgroundFetchSettledFetchPtr> settled_fetches) { @@ -262,6 +264,12 @@ if (error != blink::mojom::BackgroundFetchError::NONE) DCHECK(settled_fetches.empty()); + // TODO(crbug.com/850512): We don't need to call this for requests that're + // complete. + // AddObservedUrl() is a no-op in those cases, but we can skip calling it. + for (const auto& fetch : settled_fetches) + registration_notifier_->AddObservedUrl(unique_id, fetch->request->url); + std::move(callback).Run(std::move(settled_fetches)); }
diff --git a/content/browser/background_fetch/background_fetch_context.h b/content/browser/background_fetch/background_fetch_context.h index 4345073..1370119 100644 --- a/content/browser/background_fetch/background_fetch_context.h +++ b/content/browser/background_fetch/background_fetch_context.h
@@ -121,6 +121,10 @@ const base::Optional<SkBitmap>& icon, blink::mojom::BackgroundFetchService::UpdateUICallback callback); + BackgroundFetchRegistrationNotifier* registration_notifier() const { + return registration_notifier_.get(); + } + private: using GetPermissionCallback = base::OnceCallback<void(BackgroundFetchPermission)>; @@ -155,6 +159,7 @@ // from storage, and |callback| can be invoked to pass these on to the // renderer. void DidGetMatchingRequests( + const std::string& unique_id, blink::mojom::BackgroundFetchService::MatchRequestsCallback callback, blink::mojom::BackgroundFetchError error, std::vector<blink::mojom::BackgroundFetchSettledFetchPtr>
diff --git a/content/browser/background_fetch/background_fetch_data_manager_observer.h b/content/browser/background_fetch/background_fetch_data_manager_observer.h index fc8b4e2a..7269b04 100644 --- a/content/browser/background_fetch/background_fetch_data_manager_observer.h +++ b/content/browser/background_fetch/background_fetch_data_manager_observer.h
@@ -53,6 +53,13 @@ virtual void OnServiceWorkerDatabaseCorrupted( int64_t service_worker_registration_id) = 0; + // Called when a request has been completed, for the registration identified + // by |unique_id|. + virtual void OnRequestCompleted( + const std::string& unique_id, + blink::mojom::FetchAPIRequestPtr request, + blink::mojom::FetchAPIResponsePtr response) = 0; + virtual ~BackgroundFetchDataManagerObserver() {} };
diff --git a/content/browser/background_fetch/background_fetch_data_manager_unittest.cc b/content/browser/background_fetch/background_fetch_data_manager_unittest.cc index fe75fc90..50f29d2 100644 --- a/content/browser/background_fetch/background_fetch_data_manager_unittest.cc +++ b/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
@@ -602,6 +602,10 @@ void(blink::mojom::BackgroundFetchRegistration* registration)); MOCK_METHOD1(OnServiceWorkerDatabaseCorrupted, void(int64_t service_worker_registration_id)); + MOCK_METHOD3(OnRequestCompleted, + void(const std::string& unique_id, + blink::mojom::FetchAPIRequestPtr request, + blink::mojom::FetchAPIResponsePtr response)); protected: void DidGetRegistration( @@ -2200,4 +2204,65 @@ } } +TEST_F(BackgroundFetchDataManagerTest, NotifyObserversOnRequestCompletion) { + int64_t sw_id = RegisterServiceWorker(); + ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id); + + BackgroundFetchRegistrationId registration_id1( + sw_id, origin(), kExampleDeveloperId, kExampleUniqueId); + + std::vector<blink::mojom::FetchAPIRequestPtr> requests = + CreateValidRequests(origin(), 1u); + auto options = blink::mojom::BackgroundFetchOptions::New(); + blink::mojom::BackgroundFetchError error; + blink::mojom::BackgroundFetchFailureReason failure_reason; + + // Complete the fetch successfully, and expect an OnRequestCompleted() call. + { + CreateRegistration(registration_id1, CloneRequestVector(requests), + options.Clone(), SkBitmap(), &error); + ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE); + scoped_refptr<BackgroundFetchRequestInfo> request_info; + PopNextRequest(registration_id1, &error, &request_info); + ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE); + AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(), + /* succeeded= */ true); + EXPECT_CALL(*this, OnRequestCompleted(kExampleUniqueId, _, _)); + MarkRequestAsComplete(registration_id1, request_info.get(), &error); + EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE); + + // Mark the Registration for deletion. + MarkRegistrationForDeletion(registration_id1, /* check_for_failure= */ true, + &error, &failure_reason); + EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE); + EXPECT_EQ(failure_reason, blink::mojom::BackgroundFetchFailureReason::NONE); + } + + BackgroundFetchRegistrationId registration_id2( + sw_id, origin(), kAlternativeDeveloperId, kAlternativeUniqueId); + + // Complete the fetch with a BAD_STATUS, and expect an OnRequestCompleted() + // call. + { + CreateRegistration(registration_id2, CloneRequestVector(requests), + std::move(options), SkBitmap(), &error); + ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE); + scoped_refptr<BackgroundFetchRequestInfo> request_info; + PopNextRequest(registration_id2, &error, &request_info); + ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE); + AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get()); + EXPECT_CALL(*this, OnRequestCompleted(kAlternativeUniqueId, _, _)); + MarkRequestAsComplete(registration_id2, request_info.get(), &error); + EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE); + + // Mark the Registration for deletion. + MarkRegistrationForDeletion(registration_id2, /* check_for_failure= */ true, + &error, &failure_reason); + EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE); + // The fetch resulted in a 404. + EXPECT_EQ(failure_reason, + blink::mojom::BackgroundFetchFailureReason::BAD_STATUS); + } +} + } // namespace content
diff --git a/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc b/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc index 001c282..1d33d7d06 100644 --- a/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc +++ b/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc
@@ -20,7 +20,8 @@ void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchAbortEvent( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback callback) { + blink::mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback + callback) { last_registration_ = std::move(registration); if (fail_abort_event_) { @@ -35,7 +36,8 @@ void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchClickEvent( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback callback) { + blink::mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback + callback) { last_registration_ = std::move(registration); if (fail_click_event_) { @@ -50,7 +52,8 @@ void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchFailEvent( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback callback) { + blink::mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback + callback) { last_registration_ = std::move(registration); if (fail_fetch_fail_event_) { @@ -65,7 +68,7 @@ void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchSuccessEvent( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback + blink::mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback callback) { last_registration_ = std::move(registration);
diff --git a/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h b/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h index 80def252..a51e448 100644 --- a/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h +++ b/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h
@@ -53,19 +53,19 @@ // EmbeddedWorkerTestHelper overrides: void OnBackgroundFetchAbortEvent( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback callback) - override; + blink::mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback + callback) override; void OnBackgroundFetchClickEvent( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback callback) - override; + blink::mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback + callback) override; void OnBackgroundFetchFailEvent( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback callback) - override; + blink::mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback + callback) override; void OnBackgroundFetchSuccessEvent( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback + blink::mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback callback) override; private:
diff --git a/content/browser/background_fetch/background_fetch_event_dispatcher.h b/content/browser/background_fetch/background_fetch_event_dispatcher.h index 65c2223..96d4f00 100644 --- a/content/browser/background_fetch/background_fetch_event_dispatcher.h +++ b/content/browser/background_fetch/background_fetch_event_dispatcher.h
@@ -13,7 +13,6 @@ #include "base/memory/ref_counted.h" #include "content/browser/service_worker/service_worker_metrics.h" #include "content/common/content_export.h" -#include "content/common/service_worker/service_worker.mojom.h" namespace content {
diff --git a/content/browser/background_fetch/background_fetch_registration_notifier.cc b/content/browser/background_fetch/background_fetch_registration_notifier.cc index 41c7897b..e816f01 100644 --- a/content/browser/background_fetch/background_fetch_registration_notifier.cc +++ b/content/browser/background_fetch/background_fetch_registration_notifier.cc
@@ -5,6 +5,11 @@ #include "content/browser/background_fetch/background_fetch_registration_notifier.h" #include "base/bind.h" +#include "base/command_line.h" +#include "base/feature_list.h" +#include "content/common/background_fetch/background_fetch_types.h" +#include "content/public/common/content_features.h" +#include "content/public/common/content_switches.h" namespace content { @@ -54,6 +59,38 @@ } } +void BackgroundFetchRegistrationNotifier::AddObservedUrl( + const std::string& unique_id, + const GURL& url) { + // Ensure we have an observer for this unique_id. + if (observers_.find(unique_id) == observers_.end()) + return; + + observed_urls_[unique_id].insert(url); +} + +void BackgroundFetchRegistrationNotifier::NotifyRequestCompleted( + const std::string& unique_id, + blink::mojom::FetchAPIRequestPtr request, + blink::mojom::FetchAPIResponsePtr response) { + // Avoid sending {request, response} over the mojo pipe if no |observers_| + // care about it. + auto observed_urls_iter = observed_urls_.find(unique_id); + if (observed_urls_iter == observed_urls_.end()) + return; + if (observed_urls_iter->second.find(request->url) == + observed_urls_iter->second.end()) { + return; + } + + auto range = observers_.equal_range(unique_id); + for (auto it = range.first; it != range.second; ++it) { + it->second->OnRequestCompleted( + BackgroundFetchSettledFetch::CloneRequest(request), + BackgroundFetchSettledFetch::CloneResponse(response)); + } +} + void BackgroundFetchRegistrationNotifier::OnConnectionError( const std::string& unique_id, blink::mojom::BackgroundFetchRegistrationObserver* observer) {
diff --git a/content/browser/background_fetch/background_fetch_registration_notifier.h b/content/browser/background_fetch/background_fetch_registration_notifier.h index 8532d87..7cfee63 100644 --- a/content/browser/background_fetch/background_fetch_registration_notifier.h +++ b/content/browser/background_fetch/background_fetch_registration_notifier.h
@@ -36,10 +36,21 @@ // Completed fetches must also call Notify with the final state. void Notify(const blink::mojom::BackgroundFetchRegistration& registration); - // Notifies any registered observers for the registration identifier by + // Notifies any registered observers for the registration identified by // |unique_id| that the records for the fetch are no longer available. void NotifyRecordsUnavailable(const std::string& unique_id); + // Notifies any registered observers for the registration identified by + // |unique_id| that the |request| has completed. |response| points to the + // completed response, if any. + void NotifyRequestCompleted(const std::string& unique_id, + blink::mojom::FetchAPIRequestPtr request, + blink::mojom::FetchAPIResponsePtr response); + + // Add |url| to the list of |observed_urls_|. Once this is done, the + // |observers_| start getting updates about any requests with this URL. + void AddObservedUrl(const std::string& unique_id, const GURL& url); + base::WeakPtr<BackgroundFetchRegistrationNotifier> GetWeakPtr() { return weak_factory_.GetWeakPtr(); } @@ -56,6 +67,9 @@ blink::mojom::BackgroundFetchRegistrationObserverPtr> observers_; + // URLs the observers care about, indexed by the unique_id of the observer. + std::map<std::string, std::set<GURL>> observed_urls_; + base::WeakPtrFactory<BackgroundFetchRegistrationNotifier> weak_factory_; DISALLOW_COPY_AND_ASSIGN(BackgroundFetchRegistrationNotifier);
diff --git a/content/browser/background_fetch/background_fetch_registration_notifier_unittest.cc b/content/browser/background_fetch/background_fetch_registration_notifier_unittest.cc index 468f7605..7a9357e 100644 --- a/content/browser/background_fetch/background_fetch_registration_notifier_unittest.cc +++ b/content/browser/background_fetch/background_fetch_registration_notifier_unittest.cc
@@ -9,8 +9,11 @@ #include <vector> #include "base/macros.h" +#include "base/test/scoped_feature_list.h" #include "base/test/test_simple_task_runner.h" #include "base/threading/thread_task_runner_handle.h" +#include "content/common/background_fetch/background_fetch_types.h" +#include "content/public/common/content_features.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/interface_request.h" #include "testing/gtest/include/gtest/gtest.h" @@ -22,6 +25,7 @@ const char kDeveloperId[] = "my-fetch"; const char kPrimaryUniqueId[] = "7e57ab1e-c0de-a150-ca75-1e75f005ba11"; const char kSecondaryUniqueId[] = "bb48a9fb-c21f-4c2d-a9ae-58bd48a9fb53"; +const char kURL[] = "https://example.com"; constexpr uint64_t kDownloadTotal = 1; constexpr uint64_t kDownloaded = 2; @@ -29,6 +33,9 @@ class TestRegistrationObserver : public blink::mojom::BackgroundFetchRegistrationObserver { public: + using CompletedRequests = + std::vector<std::pair<blink::mojom::FetchAPIRequestPtr, + blink::mojom::FetchAPIResponsePtr>>; struct ProgressUpdate { ProgressUpdate(uint64_t upload_total, uint64_t uploaded, @@ -71,6 +78,12 @@ return progress_updates_; } + // Returns the vector of completed request notifications received by this + // observer. + const CompletedRequests& completed_requests() const { + return completed_requests_; + } + bool records_available() const { return records_available_; } // blink::mojom::BackgroundFetchRegistrationObserver implementation. @@ -87,8 +100,14 @@ void OnRecordsUnavailable() override { records_available_ = false; } + void OnRequestCompleted(blink::mojom::FetchAPIRequestPtr request, + blink::mojom::FetchAPIResponsePtr response) override { + completed_requests_.emplace_back(std::move(request), std::move(response)); + } + private: std::vector<ProgressUpdate> progress_updates_; + CompletedRequests completed_requests_; mojo::Binding<blink::mojom::BackgroundFetchRegistrationObserver> binding_; bool records_available_ = true; @@ -116,6 +135,19 @@ task_runner_->RunUntilIdle(); } + void NotifyRequestCompleted(const std::string& unique_id, + blink::mojom::FetchAPIRequestPtr request, + blink::mojom::FetchAPIResponsePtr response) { + notifier_->NotifyRequestCompleted(unique_id, std::move(request), + std::move(response)); + task_runner_->RunUntilIdle(); + } + + void AddObservedUrl(const std::string& unique_id, const GURL& url) { + notifier_->AddObservedUrl(unique_id, url); + task_runner_->RunUntilIdle(); + } + protected: scoped_refptr<base::TestSimpleTaskRunner> task_runner_; base::ThreadTaskRunnerHandle handle_; @@ -248,5 +280,38 @@ ASSERT_FALSE(observer->records_available()); } +TEST_F(BackgroundFetchRegistrationNotifierTest, NotifyRequestCompleted) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature( + features::kBackgroundFetchAccessActiveFetches); + ASSERT_TRUE(base::FeatureList::IsEnabled( + features::kBackgroundFetchAccessActiveFetches)); + auto observer = std::make_unique<TestRegistrationObserver>(); + + notifier_->AddObserver(kPrimaryUniqueId, observer->GetPtr()); + + // No observed URLs. Observers shouldn't have been notified. + ASSERT_EQ(observer->completed_requests().size(), 0u); + + auto request = blink::mojom::FetchAPIRequest::New(); + request->url = GURL(kURL); + + NotifyRequestCompleted(kPrimaryUniqueId, + BackgroundFetchSettledFetch::CloneRequest(request), + /* response */ nullptr); + + ASSERT_EQ(observer->completed_requests().size(), 0u); + + // Add observed URL. NotifyRequestCompleted() should now notify the observer. + AddObservedUrl(kPrimaryUniqueId, request->url); + NotifyRequestCompleted(kPrimaryUniqueId, std::move(request), + /* response */ nullptr); + + ASSERT_EQ(observer->completed_requests().size(), 1u); + auto& received_pair = observer->completed_requests()[0]; + EXPECT_EQ(received_pair.first->url, GURL(kURL)); + EXPECT_TRUE(received_pair.second.is_null()); +} + } // namespace } // namespace content
diff --git a/content/browser/background_fetch/background_fetch_scheduler.cc b/content/browser/background_fetch/background_fetch_scheduler.cc index 53dc8b7..3defb64 100644 --- a/content/browser/background_fetch/background_fetch_scheduler.cc +++ b/content/browser/background_fetch/background_fetch_scheduler.cc
@@ -13,6 +13,8 @@ #include "content/browser/background_fetch/background_fetch_registration_notifier.h" #include "content/browser/service_worker/service_worker_context_core_observer.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" +#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h" +#include "third_party/blink/public/mojom/fetch/fetch_api_response.mojom.h" namespace content { @@ -280,6 +282,14 @@ } } +void BackgroundFetchScheduler::OnRequestCompleted( + const std::string& unique_id, + blink::mojom::FetchAPIRequestPtr request, + blink::mojom::FetchAPIResponsePtr response) { + registration_notifier_->NotifyRequestCompleted(unique_id, std::move(request), + std::move(response)); +} + void BackgroundFetchScheduler::AbortFetches( int64_t service_worker_registration_id) { // Abandon all active associated with this service worker.
diff --git a/content/browser/background_fetch/background_fetch_scheduler.h b/content/browser/background_fetch/background_fetch_scheduler.h index d88a608..1cb4820 100644 --- a/content/browser/background_fetch/background_fetch_scheduler.h +++ b/content/browser/background_fetch/background_fetch_scheduler.h
@@ -71,6 +71,9 @@ int64_t service_worker_registration_id) override; void OnRegistrationQueried( blink::mojom::BackgroundFetchRegistration* registration) override; + void OnRequestCompleted(const std::string& unique_id, + blink::mojom::FetchAPIRequestPtr request, + blink::mojom::FetchAPIResponsePtr response) override; // ServiceWorkerContextCoreObserver implementation. void OnRegistrationDeleted(int64_t registration_id,
diff --git a/content/browser/background_fetch/background_fetch_service_impl.cc b/content/browser/background_fetch/background_fetch_service_impl.cc index 7d165b7..d56cc69 100644 --- a/content/browser/background_fetch/background_fetch_service_impl.cc +++ b/content/browser/background_fetch/background_fetch_service_impl.cc
@@ -12,6 +12,7 @@ #include "content/browser/background_fetch/background_fetch_context.h" #include "content/browser/background_fetch/background_fetch_metrics.h" #include "content/browser/background_fetch/background_fetch_registration_id.h" +#include "content/browser/background_fetch/background_fetch_registration_notifier.h" #include "content/browser/background_fetch/background_fetch_request_match_params.h" #include "content/browser/bad_message.h" #include "content/browser/storage_partition_impl.h"
diff --git a/content/browser/background_fetch/background_fetch_service_unittest.cc b/content/browser/background_fetch/background_fetch_service_unittest.cc index 044beb0..b56fce5 100644 --- a/content/browser/background_fetch/background_fetch_service_unittest.cc +++ b/content/browser/background_fetch/background_fetch_service_unittest.cc
@@ -347,6 +347,10 @@ void(blink::mojom::BackgroundFetchRegistration* registration)); MOCK_METHOD1(OnServiceWorkerDatabaseCorrupted, void(int64_t service_worker_registration_id)); + MOCK_METHOD3(OnRequestCompleted, + void(const std::string& unique_id, + blink::mojom::FetchAPIRequestPtr request, + blink::mojom::FetchAPIResponsePtr response)); // ServiceWorkerContextCoreObserver implementation. MOCK_METHOD2(OnRegistrationDeleted,
diff --git a/content/browser/background_fetch/storage/mark_request_complete_task.cc b/content/browser/background_fetch/storage/mark_request_complete_task.cc index 96fba8ea..e45e50d 100644 --- a/content/browser/background_fetch/storage/mark_request_complete_task.cc +++ b/content/browser/background_fetch/storage/mark_request_complete_task.cc
@@ -13,6 +13,7 @@ #include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/cache_storage/cache_storage_manager.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" +#include "content/common/background_fetch/background_fetch_types.h" #include "content/common/service_worker/service_worker_utils.h" #include "services/network/public/cpp/cors/cors.h" #include "storage/browser/blob/blob_data_builder.h" @@ -38,7 +39,7 @@ MarkRequestCompleteTask::MarkRequestCompleteTask( DatabaseTaskHost* host, - BackgroundFetchRegistrationId registration_id, + const BackgroundFetchRegistrationId& registration_id, scoped_refptr<BackgroundFetchRequestInfo> request_info, MarkRequestCompleteCallback callback) : DatabaseTask(host), @@ -60,10 +61,10 @@ } void MarkRequestCompleteTask::StoreResponse(base::OnceClosure done_closure) { - auto response = blink::mojom::FetchAPIResponse::New(); - response->url_list = request_info_->GetURLChain(); - response->response_type = network::mojom::FetchResponseType::kDefault; - response->response_time = request_info_->GetResponseTime(); + response_ = blink::mojom::FetchAPIResponse::New(); + response_->url_list = request_info_->GetURLChain(); + response_->response_type = network::mojom::FetchResponseType::kDefault; + response_->response_time = request_info_->GetResponseTime(); if (request_info_->GetURLChain().empty()) { // The URL chain was not provided, so this is a failed response. @@ -84,7 +85,7 @@ return; } - PopulateResponseBody(response.get()); + PopulateResponseBody(response_.get()); if (!IsOK(*request_info_)) failure_reason_ = proto::BackgroundFetchRegistration::BAD_STATUS; @@ -104,17 +105,14 @@ IsQuotaAvailable( registration_id_.origin(), response_size, base::BindOnce(&MarkRequestCompleteTask::DidGetIsQuotaAvailable, - weak_factory_.GetWeakPtr(), std::move(response), - std::move(done_closure))); + weak_factory_.GetWeakPtr(), std::move(done_closure))); } else { // Assume there is enough quota. - DidGetIsQuotaAvailable(std::move(response), std::move(done_closure), - true /* is_available */); + DidGetIsQuotaAvailable(std::move(done_closure), true /* is_available */); } } void MarkRequestCompleteTask::DidGetIsQuotaAvailable( - blink::mojom::FetchAPIResponsePtr response, base::OnceClosure done_closure, bool is_available) { if (!is_available) { @@ -126,8 +124,7 @@ cache_storage.value()->OpenCache( registration_id_.unique_id() /* cache_name */, base::BindOnce(&MarkRequestCompleteTask::DidOpenCache, - weak_factory_.GetWeakPtr(), std::move(response), - std::move(done_closure))); + weak_factory_.GetWeakPtr(), std::move(done_closure))); } void MarkRequestCompleteTask::PopulateResponseBody( @@ -175,7 +172,6 @@ } void MarkRequestCompleteTask::DidOpenCache( - blink::mojom::FetchAPIResponsePtr response, base::OnceClosure done_closure, CacheStorageCacheHandle handle, blink::mojom::CacheStorageError error) { @@ -188,12 +184,13 @@ DCHECK(handle.value()); blink::mojom::FetchAPIRequestPtr request = - BackgroundFetchSettledFetch::CloneRequest(request_info_->fetch_request()); + BackgroundFetchSettledFetch::CloneRequest( + request_info_->fetch_request_ptr()); // TODO(crbug.com/774054): The request blob stored in the cache is being // overwritten here, it should be written back. handle.value()->Put( - std::move(request), std::move(response), + std::move(request), BackgroundFetchSettledFetch::CloneResponse(response_), base::BindOnce(&MarkRequestCompleteTask::DidWriteToCache, weak_factory_.GetWeakPtr(), std::move(handle), std::move(done_closure))); @@ -241,6 +238,15 @@ return; } + // Notify observers that the request is complete. + for (auto& observer : data_manager()->observers()) { + observer.OnRequestCompleted( + registration_id_.unique_id(), + BackgroundFetchSettledFetch::CloneRequest( + request_info_->fetch_request_ptr()), + BackgroundFetchSettledFetch::CloneResponse(response_)); + } + // Delete the active request. service_worker_context()->ClearRegistrationUserData( registration_id_.service_worker_registration_id(),
diff --git a/content/browser/background_fetch/storage/mark_request_complete_task.h b/content/browser/background_fetch/storage/mark_request_complete_task.h index 2663f09..8d4bb259 100644 --- a/content/browser/background_fetch/storage/mark_request_complete_task.h +++ b/content/browser/background_fetch/storage/mark_request_complete_task.h
@@ -26,7 +26,7 @@ MarkRequestCompleteTask( DatabaseTaskHost* host, - BackgroundFetchRegistrationId registration_id, + const BackgroundFetchRegistrationId& registration_id, scoped_refptr<BackgroundFetchRequestInfo> request_info, MarkRequestCompleteCallback callback); @@ -40,12 +40,10 @@ void PopulateResponseBody(blink::mojom::FetchAPIResponse* response); - void DidGetIsQuotaAvailable(blink::mojom::FetchAPIResponsePtr response, - base::OnceClosure done_closure, + void DidGetIsQuotaAvailable(base::OnceClosure done_closure, bool is_available); - void DidOpenCache(blink::mojom::FetchAPIResponsePtr response, - base::OnceClosure done_closure, + void DidOpenCache(base::OnceClosure done_closure, CacheStorageCacheHandle handle, blink::mojom::CacheStorageError error); @@ -76,6 +74,7 @@ BackgroundFetchRegistrationId registration_id_; scoped_refptr<BackgroundFetchRequestInfo> request_info_; + blink::mojom::FetchAPIResponsePtr response_; MarkRequestCompleteCallback callback_; proto::BackgroundFetchCompletedRequest completed_request_;
diff --git a/content/browser/background_fetch/storage/match_requests_task.cc b/content/browser/background_fetch/storage/match_requests_task.cc index e6b024b..651b2554 100644 --- a/content/browser/background_fetch/storage/match_requests_task.cc +++ b/content/browser/background_fetch/storage/match_requests_task.cc
@@ -19,7 +19,7 @@ MatchRequestsTask::MatchRequestsTask( DatabaseTaskHost* host, - BackgroundFetchRegistrationId registration_id, + const BackgroundFetchRegistrationId& registration_id, std::unique_ptr<BackgroundFetchRequestMatchParams> match_params, SettledFetchesCallback callback) : DatabaseTask(host), @@ -48,10 +48,12 @@ handle_ = std::move(handle); DCHECK(handle_.value()); - auto request = blink::mojom::FetchAPIRequest::New(); + blink::mojom::FetchAPIRequestPtr request; if (match_params_->FilterByRequest()) { request = BackgroundFetchSettledFetch::CloneRequest( match_params_->request_to_match()); + } else { + request = blink::mojom::FetchAPIRequest::New(); } handle_.value()->GetAllMatchedEntries(
diff --git a/content/browser/background_fetch/storage/match_requests_task.h b/content/browser/background_fetch/storage/match_requests_task.h index e0861db..2e2e686 100644 --- a/content/browser/background_fetch/storage/match_requests_task.h +++ b/content/browser/background_fetch/storage/match_requests_task.h
@@ -30,7 +30,7 @@ // |match_params|. MatchRequestsTask( DatabaseTaskHost* host, - BackgroundFetchRegistrationId registration_id, + const BackgroundFetchRegistrationId& registration_id, std::unique_ptr<BackgroundFetchRequestMatchParams> match_params, SettledFetchesCallback callback);
diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc index 98761a3..1d56e5f6 100644 --- a/content/browser/background_sync/background_sync_manager.cc +++ b/content/browser/background_sync/background_sync_manager.cc
@@ -24,7 +24,6 @@ #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_storage.h" #include "content/browser/storage_partition_impl.h" -#include "content/common/service_worker/service_worker.mojom.h" #include "content/common/service_worker/service_worker_utils.h" #include "content/public/browser/background_sync_controller.h" #include "content/public/browser/browser_context.h" @@ -33,6 +32,7 @@ #include "content/public/browser/permission_controller.h" #include "content/public/browser/permission_type.h" #include "third_party/blink/public/common/service_worker/service_worker_type_converters.h" +#include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h" #if defined(OS_ANDROID)
diff --git a/content/browser/bluetooth/web_bluetooth_service_impl.cc b/content/browser/bluetooth/web_bluetooth_service_impl.cc index f061eca..e7314e8 100644 --- a/content/browser/bluetooth/web_bluetooth_service_impl.cc +++ b/content/browser/bluetooth/web_bluetooth_service_impl.cc
@@ -207,6 +207,7 @@ void WebBluetoothServiceImpl::DeviceAdded(device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (device_chooser_controller_.get()) { device_chooser_controller_->AddFilteredDevice(*device); } @@ -231,6 +232,80 @@ } } +void WebBluetoothServiceImpl::DeviceAdvertisementReceived( + const std::string& device_id, + const base::Optional<std::string>& device_name, + const base::Optional<std::string>& advertisement_name, + base::Optional<int8_t> rssi, + base::Optional<int8_t> tx_power, + uint16_t appearance, + const device::BluetoothDevice::UUIDList& advertised_uuids, + const device::BluetoothDevice::ServiceDataMap& service_data_map, + const device::BluetoothDevice::ManufacturerDataMap& manufacturer_data_map) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + if (!discovery_session_ || !discovery_session_->IsActive()) + return; + + bool has_bound_client = false; + for (auto const& client : scanning_clients_) { + if (!client.is_bound()) + continue; + + has_bound_client = true; + + // TODO(dougt): filter out devices the client is not interested in. + auto device = blink::mojom::WebBluetoothDevice::New(); + // TODO(dougt): + // Currently, Web Bluetooth (GATT Connections) obfuscate the device + // address, here called the |device->id|. However, for scanning, it + // may be desirable to expose the actual MAC. + // + // What needs to happen next is for us to figure out if we can expose + // the MAC address or if we need to obfuscate like we do with GATT + // Connections. + device->id = WebBluetoothDeviceId(device_id, /*is_mac_address=*/true); + device->name = device_name; + + auto result = blink::mojom::WebBluetoothScanResult::New(); + result->device = std::move(device); + + result->name = advertisement_name; + result->appearance = appearance; + + // TODO(dougt) rssi and tx_power should be sent as optional. + + // 128 (0x80) means invalid value + result->rssi = rssi.value_or(128); + result->tx_power = tx_power.value_or(128); + + std::vector<device::BluetoothUUID> uuids; + for (auto& uuid : advertised_uuids) + uuids.push_back(device::BluetoothUUID(uuid.canonical_value())); + result->uuids = std::move(uuids); + + auto& manufacturer_data = result->manufacturer_data; + for (auto& it : manufacturer_data_map) + manufacturer_data.emplace(it.first, it.second); + + base::flat_map<std::string, std::vector<uint8_t>> services; + for (auto& it : service_data_map) + services[it.first.canonical_value()] = it.second; + result->service_data = std::move(services); + + client->ScanEvent(std::move(result)); + } + + // TODO(dougt): Instead of this we should have a connection error handler on + // each client and remove it from |scanning_clients_| when the pipe closes. + + // If we don't have any bound clients, clean things up. + if (!discovery_request_pending_ && !has_bound_client && discovery_session_) { + scanning_clients_.clear(); + discovery_session_->Stop(base::DoNothing(), base::DoNothing()); + } +} + void WebBluetoothServiceImpl::GattServicesDiscovered( device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { @@ -818,6 +893,91 @@ weak_ptr_factory_.GetWeakPtr(), copyable_callback)); } +void WebBluetoothServiceImpl::RequestScanningStart( + blink::mojom::WebBluetoothScanClientAssociatedPtrInfo client_info, + RequestScanningStartCallback callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + blink::mojom::WebBluetoothScanClientAssociatedPtr client; + client.Bind(std::move(client_info)); + + if (!GetAdapter()) { + if (BluetoothAdapterFactoryWrapper::Get().IsLowEnergySupported()) { + BluetoothAdapterFactoryWrapper::Get().AcquireAdapter( + this, base::Bind(&WebBluetoothServiceImpl::RequestScanningStartImpl, + weak_ptr_factory_.GetWeakPtr(), + base::Passed(&client), base::Passed(&callback))); + return; + } + + std::move(callback).Run( + blink::mojom::WebBluetoothResult::BLUETOOTH_LOW_ENERGY_NOT_AVAILABLE); + return; + } + + RequestScanningStartImpl(std::move(client), std::move(callback), + GetAdapter()); +} + +void WebBluetoothServiceImpl::RequestScanningStartImpl( + blink::mojom::WebBluetoothScanClientAssociatedPtr client, + RequestScanningStartCallback callback, + device::BluetoothAdapter* adapter) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + if (!adapter) { + std::move(callback).Run( + blink::mojom::WebBluetoothResult::BLUETOOTH_LOW_ENERGY_NOT_AVAILABLE); + return; + } + + if (discovery_session_) { + scanning_clients_.push_back(std::move(client)); + std::move(callback).Run(blink::mojom::WebBluetoothResult::SUCCESS); + return; + } + + discovery_callbacks_.push_back(std::move(callback)); + + if (discovery_request_pending_) + return; + + discovery_request_pending_ = true; + adapter->StartDiscoverySession( + base::Bind(&WebBluetoothServiceImpl::OnStartDiscoverySession, + weak_ptr_factory_.GetWeakPtr(), base::Passed(&client)), + base::Bind(&WebBluetoothServiceImpl::OnDiscoverySessionError, + weak_ptr_factory_.GetWeakPtr())); +} + +void WebBluetoothServiceImpl::OnStartDiscoverySession( + blink::mojom::WebBluetoothScanClientAssociatedPtr client, + std::unique_ptr<device::BluetoothDiscoverySession> session) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(!discovery_session_); + + discovery_request_pending_ = false; + discovery_session_ = std::move(session); + scanning_clients_.push_back(std::move(client)); + + for (auto& callback : discovery_callbacks_) + std::move(callback).Run(blink::mojom::WebBluetoothResult::SUCCESS); + + discovery_callbacks_.clear(); +} + +void WebBluetoothServiceImpl::OnDiscoverySessionError() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + discovery_request_pending_ = false; + + for (auto& callback : discovery_callbacks_) { + std::move(callback).Run( + blink::mojom::WebBluetoothResult::NO_BLUETOOTH_ADAPTER); + } + + discovery_callbacks_.clear(); +} + void WebBluetoothServiceImpl::RequestDeviceImpl( blink::mojom::WebBluetoothRequestDeviceOptionsPtr options, RequestDeviceCallback callback, @@ -935,14 +1095,13 @@ DVLOG(1) << "Device: " << device->GetNameForDisplay(); - blink::mojom::WebBluetoothDevicePtr device_ptr = - blink::mojom::WebBluetoothDevice::New(); - device_ptr->id = device_id; - device_ptr->name = device->GetName(); + auto web_bluetooth_device = blink::mojom::WebBluetoothDevice::New(); + web_bluetooth_device->id = device_id; + web_bluetooth_device->name = device->GetName(); RecordRequestDeviceOutcome(UMARequestDeviceOutcome::SUCCESS); std::move(callback).Run(blink::mojom::WebBluetoothResult::SUCCESS, - std::move(device_ptr)); + std::move(web_bluetooth_device)); } void WebBluetoothServiceImpl::OnGetDeviceFailed( @@ -1247,6 +1406,7 @@ binding_.Close(); characteristic_id_to_notify_session_.clear(); + scanning_clients_.clear(); pending_primary_services_requests_.clear(); descriptor_id_to_characteristic_id_.clear(); characteristic_id_to_service_id_.clear();
diff --git a/content/browser/bluetooth/web_bluetooth_service_impl.h b/content/browser/bluetooth/web_bluetooth_service_impl.h index 55b409a..2fbbb64 100644 --- a/content/browser/bluetooth/web_bluetooth_service_impl.h +++ b/content/browser/bluetooth/web_bluetooth_service_impl.h
@@ -16,6 +16,7 @@ #include "content/common/content_export.h" #include "content/public/browser/web_contents_observer.h" #include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_discovery_session.h" #include "device/bluetooth/bluetooth_gatt_connection.h" #include "device/bluetooth/bluetooth_gatt_notify_session.h" #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h" @@ -83,6 +84,17 @@ device::BluetoothDevice* device) override; void DeviceChanged(device::BluetoothAdapter* adapter, device::BluetoothDevice* device) override; + void DeviceAdvertisementReceived( + const std::string& device_address, + const base::Optional<std::string>& device_name, + const base::Optional<std::string>& advertisement_name, + base::Optional<int8_t> rssi, + base::Optional<int8_t> tx_power, + uint16_t appearance, + const device::BluetoothDevice::UUIDList& advertised_uuids, + const device::BluetoothDevice::ServiceDataMap& service_data_map, + const device::BluetoothDevice::ManufacturerDataMap& manufacturer_data_map) + override; void GattServicesDiscovered(device::BluetoothAdapter* adapter, device::BluetoothDevice* device) override; void GattCharacteristicValueChanged( @@ -141,12 +153,26 @@ const std::string& descriptor_instance_id, const std::vector<uint8_t>& value, RemoteDescriptorWriteValueCallback callback) override; + void RequestScanningStart( + blink::mojom::WebBluetoothScanClientAssociatedPtrInfo client, + RequestScanningStartCallback callback) override; void RequestDeviceImpl( blink::mojom::WebBluetoothRequestDeviceOptionsPtr options, RequestDeviceCallback callback, device::BluetoothAdapter* adapter); + void RequestScanningStartImpl( + blink::mojom::WebBluetoothScanClientAssociatedPtr client, + RequestScanningStartCallback callback, + device::BluetoothAdapter* adapter); + + void OnStartDiscoverySession( + blink::mojom::WebBluetoothScanClientAssociatedPtr client, + std::unique_ptr<device::BluetoothDiscoverySession> session); + + void OnDiscoverySessionError(); + // Should only be run after the services have been discovered for // |device_address|. void RemoteServerGetPrimaryServicesImpl( @@ -282,6 +308,20 @@ // The RFH that owns this instance. RenderFrameHost* render_frame_host_; + // True, if there is a pending request to start or stop discovery. + bool discovery_request_pending_ = false; + + // Keeps track of our BLE scanning session. + std::unique_ptr<device::BluetoothDiscoverySession> discovery_session_; + + // This vector queues up start callbacks so that we only have one + // BluetoothDiscoverySession start request at a time. + std::vector<RequestScanningStartCallback> discovery_callbacks_; + + // List of clients that we must broadcast scan changes to. + std::vector<blink::mojom::WebBluetoothScanClientAssociatedPtr> + scanning_clients_; + // The lifetime of this instance is exclusively managed by the RFH that // owns it so we use a "Binding" as opposed to a "StrongBinding" which deletes // the service on pipe connection errors.
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 154b8398..a43a30d 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -1019,6 +1019,17 @@ base::BindOnce( base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed), true)); + // Also allow waiting to join threads. + // TODO(https://crbug.com/800808): Ideally this (and the above SetIOAllowed() + // would be scoped allowances). That would be one of the first step to ensure + // no persistent work is being done after TaskScheduler::Shutdown() in order + // to move towards atomic shutdown. + base::ThreadRestrictions::SetWaitAllowed(true); + base::PostTaskWithTraits( + FROM_HERE, {BrowserThread::IO}, + base::BindOnce( + base::IgnoreResult(&base::ThreadRestrictions::SetWaitAllowed), true)); + #if defined(OS_ANDROID) g_browser_main_loop_shutting_down = true; #endif @@ -1096,16 +1107,13 @@ save_file_manager_->Shutdown(); { - base::ScopedAllowBaseSyncPrimitives allow_wait_for_join; - { - TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:IOThread"); - ResetThread_IO(std::move(io_thread_)); - } + TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:IOThread"); + ResetThread_IO(std::move(io_thread_)); + } - { - TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:TaskScheduler"); - base::TaskScheduler::GetInstance()->Shutdown(); - } + { + TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:TaskScheduler"); + base::TaskScheduler::GetInstance()->Shutdown(); } // Must happen after the IO thread is shutdown since this may be accessed from
diff --git a/content/browser/cache_storage/cache_storage_cache.cc b/content/browser/cache_storage/cache_storage_cache.cc index 86b1804..49af6eb 100644 --- a/content/browser/cache_storage/cache_storage_cache.cc +++ b/content/browser/cache_storage/cache_storage_cache.cc
@@ -885,8 +885,6 @@ const blink::mojom::FetchAPIRequestPtr& request) { size_t size = sizeof(*request); size += request->url.spec().size(); - if (request->client_id.has_value()) - size += request->client_id.value().size(); for (const auto& key_and_value : request->headers) { size += key_and_value.first.size();
diff --git a/content/browser/child_process_security_policy_impl.cc b/content/browser/child_process_security_policy_impl.cc index c3c9689..41d7b99 100644 --- a/content/browser/child_process_security_policy_impl.cc +++ b/content/browser/child_process_security_policy_impl.cc
@@ -441,8 +441,26 @@ } void ChildProcessSecurityPolicyImpl::Remove(int child_id) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); base::AutoLock lock(lock_); + + auto state = security_state_.find(child_id); + if (state == security_state_.end()) + return; + + pending_remove_state_[child_id] = std::move(state->second); security_state_.erase(child_id); + + base::PostTaskWithTraits( + FROM_HERE, {BrowserThread::IO}, + base::BindOnce(&ChildProcessSecurityPolicyImpl::RemovePendingIDOnIOThread, + base::Unretained(this), child_id)); +} + +void ChildProcessSecurityPolicyImpl::RemovePendingIDOnIOThread(int child_id) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + base::AutoLock lock(lock_); + pending_remove_state_.erase(child_id); } void ChildProcessSecurityPolicyImpl::RegisterWebSafeScheme( @@ -1151,21 +1169,20 @@ SiteInstanceImpl::DetermineProcessLockURL(nullptr, url); base::AutoLock lock(lock_); - auto state = security_state_.find(child_id); - if (state == security_state_.end()) { - // TODO(nick): Returning true instead of false here is a temporary - // workaround for https://crbug.com/600441 - return true; - } - bool can_access = - state->second->CanAccessDataForOrigin(expected_process_lock); + SecurityState* security_state = GetSecurityState(child_id); + + bool can_access = security_state && security_state->CanAccessDataForOrigin( + expected_process_lock); if (!can_access) { // Returning false here will result in a renderer kill. Set some crash // keys that will help understand the circumstances of that kill. base::debug::SetCrashKeyString(bad_message::GetRequestedSiteURLKey(), expected_process_lock.spec()); + base::debug::SetCrashKeyString(bad_message::GetKilledProcessOriginLockKey(), - state->second->origin_lock().spec()); + security_state + ? security_state->origin_lock().spec() + : "(child id not found)"); static auto* requested_origin_key = base::debug::AllocateCrashKeyString( "requested_origin", base::debug::CrashKeySize::Size64); @@ -1367,4 +1384,22 @@ isolated_origins_.erase(key); } +ChildProcessSecurityPolicyImpl::SecurityState* +ChildProcessSecurityPolicyImpl::GetSecurityState(int child_id) { + auto itr = security_state_.find(child_id); + if (itr != security_state_.end()) + return itr->second.get(); + + if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { + // Checking to see if |child_id| is in the pending removal map since this + // may be a call that was already on the IO thread task queue when the + // Remove() call occurred on the UI thread. + itr = pending_remove_state_.find(child_id); + if (itr != pending_remove_state_.end()) + return itr->second.get(); + } + + return nullptr; +} + } // namespace content
diff --git a/content/browser/child_process_security_policy_impl.h b/content/browser/child_process_security_policy_impl.h index 82d5dd4..271a5685 100644 --- a/content/browser/child_process_security_policy_impl.h +++ b/content/browser/child_process_security_policy_impl.h
@@ -162,6 +162,10 @@ // Upon destruction, child processess should unregister themselves by caling // this method exactly once. + // + // Note: IO thread is expected to keep pre-Remove() permissions until + // RemovePendingIDOnIOThread() runs on the IO thread. The UI thread is + // expected to have no permissions after Remove() returns. void Remove(int child_id); // Whenever the browser processes commands the child process to commit a URL, @@ -367,6 +371,14 @@ const std::string& filesystem_id, int permission); + // Removes |child_id| from |pending_remove_state_| on the IO thread. + void RemovePendingIDOnIOThread(int child_id); + + // Gets the SecurityState object associated with |child_id|. + // Note: Returned object is only valid for the duration the caller holds + // |lock_|. + SecurityState* GetSecurityState(int child_id) EXCLUSIVE_LOCKS_REQUIRED(lock_); + // You must acquire this lock before reading or writing any members of this // class. You must not block while holding this lock. base::Lock lock_; @@ -388,6 +400,13 @@ // not escape this class. SecurityStateMap security_state_ GUARDED_BY(lock_); + // This map holds the SecurityState for a child process after Remove() + // is called on the UI thread and until RemovePendingIDOnIOThread() is + // called on the IO thread. This is necessary to provide consistent + // security decisions and avoid races between the UI & IO threads during + // child process shutdown. + SecurityStateMap pending_remove_state_ GUARDED_BY(lock_); + FileSystemPermissionPolicyMap file_system_policy_map_ GUARDED_BY(lock_); // Tracks origins for which the entire origin should be treated as a site
diff --git a/content/browser/child_process_security_policy_unittest.cc b/content/browser/child_process_security_policy_unittest.cc index 3101bc1..3d43ebc 100644 --- a/content/browser/child_process_security_policy_unittest.cc +++ b/content/browser/child_process_security_policy_unittest.cc
@@ -7,6 +7,8 @@ #include "base/files/file_path.h" #include "base/logging.h" +#include "base/synchronization/waitable_event.h" +#include "base/test/bind_test_util.h" #include "base/test/mock_log.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/site_instance_impl.h" @@ -59,7 +61,9 @@ class ChildProcessSecurityPolicyTest : public testing::Test { public: - ChildProcessSecurityPolicyTest() : old_browser_client_(nullptr) {} + ChildProcessSecurityPolicyTest() + : thread_bundle_(TestBrowserThreadBundle::REAL_IO_THREAD), + old_browser_client_(nullptr) {} void SetUp() override { old_browser_client_ = SetBrowserClientForTesting(&test_browser_client_); @@ -993,6 +997,85 @@ EXPECT_FALSE(p->HasWebUIBindings(kRendererID)); } +TEST_F(ChildProcessSecurityPolicyTest, RemoveRace_CanAccessDataForOrigin) { + ChildProcessSecurityPolicyImpl* p = + ChildProcessSecurityPolicyImpl::GetInstance(); + + GURL url("file:///etc/passwd"); + + p->Add(kRendererID); + + base::WaitableEvent ready_for_remove_event; + base::WaitableEvent remove_called_event; + base::WaitableEvent pending_remove_complete_event; + + bool io_before_remove = false; + bool io_while_remove_pending = false; + bool io_after_remove_complete = false; + bool ui_before_remove = false; + bool ui_while_remove_pending = false; + bool ui_after_remove_complete = false; + + // Post a task that will run on the IO thread before the task that + // Remove() will post to the IO thread. + base::PostTaskWithTraits( + FROM_HERE, {BrowserThread::IO}, base::BindLambdaForTesting([&]() { + // Capture state on the IO thread before Remove() is called. + io_before_remove = p->CanAccessDataForOrigin(kRendererID, url); + + // Tell the UI thread we are ready for Remove() to be called. + ready_for_remove_event.Signal(); + + // Wait for Remove() to be called on the UI thread. + remove_called_event.Wait(); + + // Capture state after Remove() is called, but before its task on + // the IO thread runs. + io_while_remove_pending = p->CanAccessDataForOrigin(kRendererID, url); + })); + + ready_for_remove_event.Wait(); + + ui_before_remove = p->CanAccessDataForOrigin(kRendererID, url); + + p->Remove(kRendererID); + + // Post a task to run after the task Remove() posted on the IO thread. + base::PostTaskWithTraits( + FROM_HERE, {BrowserThread::IO}, base::BindLambdaForTesting([&]() { + io_after_remove_complete = p->CanAccessDataForOrigin(kRendererID, url); + + // Tell the UI thread that the task from Remove() has completed on the + // IO thread. + pending_remove_complete_event.Signal(); + })); + + // Capture state after Remove() has been called, but before its IO thread + // task has run. We know the IO thread task hasn't run yet because the + // task we posted before the Remove() call is waiting for us to signal + // |remove_called_event|. + ui_while_remove_pending = p->CanAccessDataForOrigin(kRendererID, url); + + // Unblock the IO thread so the pending remove events can run. + remove_called_event.Signal(); + + pending_remove_complete_event.Wait(); + + ui_after_remove_complete = p->CanAccessDataForOrigin(kRendererID, url); + + // Verify expected states at various parts of the removal. + // Note: IO thread is expected to keep pre-Remove() permissions until its + // remove task runs on the IO thread. The UI thread is expected to have no + // permissions after Remove() returns. + EXPECT_TRUE(io_before_remove); + EXPECT_TRUE(io_while_remove_pending); + EXPECT_FALSE(io_after_remove_complete); + + EXPECT_TRUE(ui_before_remove); + EXPECT_FALSE(ui_while_remove_pending); + EXPECT_FALSE(ui_after_remove_complete); +} + // Test the granting of origin permissions, and their interactions with // granting scheme permissions. TEST_F(ChildProcessSecurityPolicyTest, OriginGranting) {
diff --git a/content/browser/compositor/viz_process_transport_factory.cc b/content/browser/compositor/viz_process_transport_factory.cc index ccdcc3e..f36d42f3 100644 --- a/content/browser/compositor/viz_process_transport_factory.cc +++ b/content/browser/compositor/viz_process_transport_factory.cc
@@ -117,22 +117,23 @@ gpu::GpuChannelEstablishFactory* gpu_channel_establish_factory, scoped_refptr<base::SingleThreadTaskRunner> resize_task_runner, viz::CompositingModeReporterImpl* compositing_mode_reporter) - : ui::HostContextFactoryPrivate( + : gpu_channel_establish_factory_(gpu_channel_establish_factory), + compositing_mode_reporter_(compositing_mode_reporter), + task_graph_runner_(std::make_unique<cc::SingleThreadTaskGraphRunner>()), + context_factory_private_( kBrowserClientId, BrowserMainLoop::GetInstance()->host_frame_sink_manager(), resize_task_runner), - gpu_channel_establish_factory_(gpu_channel_establish_factory), - compositing_mode_reporter_(compositing_mode_reporter), - task_graph_runner_(std::make_unique<cc::SingleThreadTaskGraphRunner>()), weak_ptr_factory_(this) { DCHECK(gpu_channel_establish_factory_); task_graph_runner_->Start("CompositorTileWorker1", base::SimpleThread::Options()); - GetHostFrameSinkManager()->SetConnectionLostCallback( + context_factory_private_.GetHostFrameSinkManager()->SetConnectionLostCallback( base::BindRepeating(&VizProcessTransportFactory::OnGpuProcessLost, weak_ptr_factory_.GetWeakPtr())); - GetHostFrameSinkManager()->SetBadMessageReceivedFromGpuCallback( - base::BindRepeating(&ReceivedBadMessageFromGpuProcess)); + context_factory_private_.GetHostFrameSinkManager() + ->SetBadMessageReceivedFromGpuCallback( + base::BindRepeating(&ReceivedBadMessageFromGpuProcess)); base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(switches::kDisableGpu) || @@ -157,8 +158,9 @@ mojo::MakeRequest(&frame_sink_manager_client); // Setup HostFrameSinkManager with interface endpoints. - GetHostFrameSinkManager()->BindAndSetManager( - std::move(frame_sink_manager_client_request), resize_task_runner(), + context_factory_private_.GetHostFrameSinkManager()->BindAndSetManager( + std::move(frame_sink_manager_client_request), + context_factory_private_.resize_task_runner(), std::move(frame_sink_manager)); if (GpuDataManagerImpl::GetInstance()->GpuProcessStartAllowed()) { @@ -213,10 +215,9 @@ // Create the data map entry so that we can set properties like output secure // while we are waiting for the GpuChannel to be established. - AddCompositor(compositor.get()); + context_factory_private_.AddCompositor(compositor.get()); - if (is_gpu_compositing_disabled() || - compositor->force_software_compositor()) { + if (IsGpuCompositingDisabled() || compositor->force_software_compositor()) { OnEstablishedGpuChannel(compositor, nullptr); return; } @@ -227,7 +228,7 @@ scoped_refptr<viz::ContextProvider> VizProcessTransportFactory::SharedMainThreadContextProvider() { - if (is_gpu_compositing_disabled()) + if (IsGpuCompositingDisabled()) return nullptr; if (!main_context_provider_) { @@ -247,7 +248,7 @@ } void VizProcessTransportFactory::RemoveCompositor(ui::Compositor* compositor) { - UnconfigureCompositor(compositor); + context_factory_private_.UnconfigureCompositor(compositor); } gpu::GpuMemoryBufferManager* @@ -276,12 +277,12 @@ } void VizProcessTransportFactory::DisableGpuCompositing() { - if (!is_gpu_compositing_disabled()) + if (!IsGpuCompositingDisabled()) DisableGpuCompositing(nullptr); } bool VizProcessTransportFactory::IsGpuCompositingDisabled() { - return is_gpu_compositing_disabled(); + return context_factory_private_.is_gpu_compositing_disabled(); } ui::ContextFactory* VizProcessTransportFactory::GetContextFactory() { @@ -290,7 +291,7 @@ ui::ContextFactoryPrivate* VizProcessTransportFactory::GetContextFactoryPrivate() { - return this; + return &context_factory_private_; } void VizProcessTransportFactory::OnContextLost() { @@ -307,7 +308,7 @@ DLOG(ERROR) << "Switching to software compositing."; // Change the result of IsGpuCompositingDisabled() before notifying anything. - set_is_gpu_compositing_disabled(true); + context_factory_private_.set_is_gpu_compositing_disabled(true); compositing_mode_reporter_->SetUsingSoftwareCompositing(); @@ -325,7 +326,7 @@ // Reemove the FrameSink from every compositor that needs to fall back to // software compositing. - for (ui::Compositor* compositor : GetAllCompositors()) { + for (auto* compositor : context_factory_private_.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. @@ -362,8 +363,8 @@ if (!compositor) return; - bool gpu_compositing = !is_gpu_compositing_disabled() && - !compositor->force_software_compositor(); + bool gpu_compositing = + !IsGpuCompositingDisabled() && !compositor->force_software_compositor(); if (gpu_compositing) { auto context_result = @@ -387,14 +388,14 @@ compositor_context = main_context_provider_; worker_context = worker_context_provider_; } - ConfigureCompositor(compositor, std::move(compositor_context), - std::move(worker_context)); + context_factory_private_.ConfigureCompositor( + compositor, 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(!IsGpuCompositingDisabled()); // Fallback to software compositing if there is no IPC channel. if (!gpu_channel_host) @@ -459,7 +460,8 @@ kCompositorContextSupportsRaster, kCompositorContextSupportsGrContext, kCompositorContextSupportsOOPR, ws::command_buffer_metrics::ContextType::BROWSER_MAIN_THREAD); - main_context_provider_->SetDefaultTaskRunner(resize_task_runner()); + main_context_provider_->SetDefaultTaskRunner( + context_factory_private_.resize_task_runner()); auto context_result = main_context_provider_->BindToCurrentThread(); if (context_result != gpu::ContextResult::kSuccess) {
diff --git a/content/browser/compositor/viz_process_transport_factory.h b/content/browser/compositor/viz_process_transport_factory.h index e0df3563..af01023 100644 --- a/content/browser/compositor/viz_process_transport_factory.h +++ b/content/browser/compositor/viz_process_transport_factory.h
@@ -47,7 +47,6 @@ // instead of in the browser process. Any interaction with the display // compositor must happen over IPC. class VizProcessTransportFactory : public ui::ContextFactory, - public ui::HostContextFactoryPrivate, public ImageTransportFactory, public viz::ContextLostObserver { public: @@ -130,6 +129,7 @@ // Will start and run the VizCompositorThread for using an in-process display // compositor. std::unique_ptr<viz::VizCompositorThreadRunner> viz_compositor_thread_; + ui::HostContextFactoryPrivate context_factory_private_; base::WeakPtrFactory<VizProcessTransportFactory> weak_ptr_factory_;
diff --git a/content/browser/cookie_store/cookie_store_manager_unittest.cc b/content/browser/cookie_store/cookie_store_manager_unittest.cc index e9cf653..5fc07da 100644 --- a/content/browser/cookie_store/cookie_store_manager_unittest.cc +++ b/content/browser/cookie_store/cookie_store_manager_unittest.cc
@@ -13,10 +13,10 @@ #include "content/browser/service_worker/embedded_worker_test_helper.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/storage_partition_impl.h" -#include "content/common/service_worker/service_worker.mojom.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h" #include "url/gurl.h" @@ -116,7 +116,7 @@ const GURL& scope, const GURL& script_url, bool pause_after_download, - mojom::ServiceWorkerRequest service_worker_request, + blink::mojom::ServiceWorkerRequest service_worker_request, blink::mojom::ControllerServiceWorkerRequest controller_request, mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host, mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info, @@ -135,8 +135,8 @@ } // Cookie change subscriptions can only be created in this event handler. - void OnInstallEvent( - mojom::ServiceWorker::DispatchInstallEventCallback callback) override { + void OnInstallEvent(blink::mojom::ServiceWorker::DispatchInstallEventCallback + callback) override { for (auto& subscriptions : install_subscription_batches_) { cookie_store_service_->AppendSubscriptions( service_worker_registration_id_, std::move(subscriptions), @@ -151,7 +151,8 @@ // Used to implement WaitForActivateEvent(). void OnActivateEvent( - mojom::ServiceWorker::DispatchActivateEventCallback callback) override { + blink::mojom::ServiceWorker::DispatchActivateEventCallback callback) + override { if (quit_on_activate_) { quit_on_activate_->Quit(); quit_on_activate_ = nullptr; @@ -163,7 +164,7 @@ void OnCookieChangeEvent( const net::CanonicalCookie& cookie, ::network::mojom::CookieChangeCause cause, - mojom::ServiceWorker::DispatchCookieChangeEventCallback callback) + blink::mojom::ServiceWorker::DispatchCookieChangeEventCallback callback) override { changes_.emplace_back(cookie, cause); std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
diff --git a/content/browser/devtools/devtools_http_handler.cc b/content/browser/devtools/devtools_http_handler.cc index 42134d8b..2fab142 100644 --- a/content/browser/devtools/devtools_http_handler.cc +++ b/content/browser/devtools/devtools_http_handler.cc
@@ -223,7 +223,8 @@ thread->task_runner()->DeleteSoon(FROM_HERE, std::move(socket_factory)); if (thread) { base::PostTaskWithTraits( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + FROM_HERE, + {base::WithBaseSyncPrimitives(), base::TaskPriority::BEST_EFFORT}, BindOnce([](std::unique_ptr<base::Thread>) {}, std::move(thread))); } }
diff --git a/content/browser/do_not_track_browsertest.cc b/content/browser/do_not_track_browsertest.cc index ae899a2a..08f58a3 100644 --- a/content/browser/do_not_track_browsertest.cc +++ b/content/browser/do_not_track_browsertest.cc
@@ -27,16 +27,25 @@ public: void UpdateRendererPreferencesForWorker(BrowserContext*, RendererPreferences* prefs) override { - prefs->enable_do_not_track = true; - prefs->enable_referrers = true; + if (do_not_track_enabled_) { + prefs->enable_do_not_track = true; + prefs->enable_referrers = true; + } } + + void EnableDoNotTrack() { do_not_track_enabled_ = true; } + + private: + bool do_not_track_enabled_ = false; }; class DoNotTrackTest : public ContentBrowserTest { protected: + void SetUpOnMainThread() override { + original_client_ = SetBrowserClientForTesting(&client_); + } void TearDownOnMainThread() override { - if (original_client_) - SetBrowserClientForTesting(original_client_); + SetBrowserClientForTesting(original_client_); } // Returns false if we cannot enable do not track. It happens only when @@ -52,7 +61,7 @@ if (major_version < 5) return false; #endif - original_client_ = SetBrowserClientForTesting(&client_); + client_.EnableDoNotTrack(); RendererPreferences* prefs = shell()->web_contents()->GetMutableRendererPrefs(); EXPECT_FALSE(prefs->enable_do_not_track);
diff --git a/content/browser/dom_storage/session_storage_context_mojo_unittest.cc b/content/browser/dom_storage/session_storage_context_mojo_unittest.cc index c701b61..ebf479c 100644 --- a/content/browser/dom_storage/session_storage_context_mojo_unittest.cc +++ b/content/browser/dom_storage/session_storage_context_mojo_unittest.cc
@@ -17,6 +17,7 @@ #include "base/test/bind_test_util.h" #include "base/test/scoped_feature_list.h" #include "components/services/leveldb/public/cpp/util.h" +#include "content/browser/child_process_security_policy_impl.h" #include "content/browser/dom_storage/session_storage_database.h" #include "content/browser/dom_storage/test/fake_leveldb_database_error_on_write.h" #include "content/browser/dom_storage/test/fake_leveldb_service.h" @@ -62,9 +63,13 @@ features_.InitAndEnableFeature(blink::features::kOnionSoupDOMStorage); mojo::core::SetDefaultProcessErrorCallback(base::BindRepeating( &SessionStorageContextMojoTest::OnBadMessage, base::Unretained(this))); + + ChildProcessSecurityPolicyImpl::GetInstance()->Add(kTestProcessId); } void TearDown() override { + ChildProcessSecurityPolicyImpl::GetInstance()->Remove(kTestProcessId); + mojo::core::SetDefaultProcessErrorCallback( mojo::core::ProcessErrorCallback()); }
diff --git a/content/browser/dom_storage/test/mojo_test_with_file_service.h b/content/browser/dom_storage/test/mojo_test_with_file_service.h index 77d6eae..8ae2bbb 100644 --- a/content/browser/dom_storage/test/mojo_test_with_file_service.h +++ b/content/browser/dom_storage/test/mojo_test_with_file_service.h
@@ -10,7 +10,7 @@ #include "base/files/file_path.h" #include "base/files/scoped_temp_dir.h" #include "base/macros.h" -#include "base/test/scoped_task_environment.h" +#include "content/public/test/test_browser_thread_bundle.h" #include "services/file/file_service.h" #include "services/service_manager/public/cpp/test/test_connector_factory.h" #include "testing/gtest/include/gtest/gtest.h" @@ -34,10 +34,10 @@ return test_connector_factory_.GetDefaultConnector(); } - void RunUntilIdle() { scoped_task_environment_.RunUntilIdle(); } + void RunUntilIdle() { thread_bundle_.RunUntilIdle(); } private: - base::test::ScopedTaskEnvironment scoped_task_environment_; + TestBrowserThreadBundle thread_bundle_; service_manager::TestConnectorFactory test_connector_factory_; file::FileService file_service_; base::ScopedTempDir temp_path_;
diff --git a/content/browser/fileapi/browser_file_system_helper_unittest.cc b/content/browser/fileapi/browser_file_system_helper_unittest.cc index 1b0cff4..67e528b5 100644 --- a/content/browser/fileapi/browser_file_system_helper_unittest.cc +++ b/content/browser/fileapi/browser_file_system_helper_unittest.cc
@@ -13,6 +13,7 @@ #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/fileapi/browser_file_system_helper.h" #include "content/public/common/drop_data.h" +#include "content/public/test/test_browser_thread_bundle.h" #include "net/base/filename_util.h" #include "storage/browser/fileapi/external_mount_points.h" #include "storage/browser/fileapi/file_system_options.h" @@ -33,6 +34,7 @@ base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + TestBrowserThreadBundle thread_bundle; ChildProcessSecurityPolicyImpl* p = ChildProcessSecurityPolicyImpl::GetInstance(); p->Add(kRendererID); @@ -136,6 +138,7 @@ base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + TestBrowserThreadBundle thread_bundle; ChildProcessSecurityPolicyImpl* p = ChildProcessSecurityPolicyImpl::GetInstance(); p->Add(kRendererID);
diff --git a/content/browser/gpu/gpu_data_manager_testing_arrays_and_structs_autogen.h b/content/browser/gpu/gpu_data_manager_testing_arrays_and_structs_autogen.h index 1acfebb..e455d1ea 100644 --- a/content/browser/gpu/gpu_data_manager_testing_arrays_and_structs_autogen.h +++ b/content/browser/gpu/gpu_data_manager_testing_arrays_and_structs_autogen.h
@@ -23,7 +23,10 @@ }; const GpuControlList::GLStrings kGLStringsForGpuManagerTestingEntry2 = { - nullptr, ".*GeForce.*", nullptr, nullptr, + nullptr, + ".*GeForce.*", + nullptr, + nullptr, }; const int kFeatureListForGpuManagerTestingEntry3[1] = { @@ -31,11 +34,15 @@ }; const int kFeatureListForGpuManagerTestingEntry4[2] = { - GPU_FEATURE_TYPE_ACCELERATED_WEBGL2, GPU_FEATURE_TYPE_ACCELERATED_WEBGL, + GPU_FEATURE_TYPE_ACCELERATED_WEBGL2, + GPU_FEATURE_TYPE_ACCELERATED_WEBGL, }; const GpuControlList::GLStrings kGLStringsForGpuManagerTestingEntry4 = { - nullptr, ".*GeForce.*", nullptr, nullptr, + nullptr, + ".*GeForce.*", + nullptr, + nullptr, }; const int kFeatureListForGpuManagerTestingEntry5[1] = { @@ -44,7 +51,10 @@ const GpuControlList::GLStrings kGLStringsForGpuManagerTestingEntry5Exception0 = { - nullptr, ".*GeForce.*", nullptr, nullptr, + nullptr, + ".*GeForce.*", + nullptr, + nullptr, }; const int kFeatureListForGpuManagerTestingEntry6[12] = {
diff --git a/content/browser/media/capture/desktop_capture_device.cc b/content/browser/media/capture/desktop_capture_device.cc index 64dd8cb..ef2d53d 100644 --- a/content/browser/media/capture/desktop_capture_device.cc +++ b/content/browser/media/capture/desktop_capture_device.cc
@@ -558,7 +558,9 @@ void DesktopCaptureDevice::StopAndDeAllocate() { if (core_) { - base::ThreadRestrictions::ScopedAllowIO allow_io; + // This thread should mostly be an idle observer. Stopping it should be + // fast. + base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_thread_join; thread_.task_runner()->DeleteSoon(FROM_HERE, core_.release()); thread_.Stop(); }
diff --git a/content/browser/media/session/audio_focus_delegate_default.cc b/content/browser/media/session/audio_focus_delegate_default.cc index 9d0c464..9962a55 100644 --- a/content/browser/media/session/audio_focus_delegate_default.cc +++ b/content/browser/media/session/audio_focus_delegate_default.cc
@@ -6,7 +6,6 @@ #include "base/no_destructor.h" #include "base/unguessable_token.h" -#include "build/build_config.h" #include "content/browser/media/session/media_session_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/service_manager_connection.h" @@ -23,20 +22,10 @@ const char kAudioFocusSourceName[] = "web"; -base::UnguessableToken GetAudioFocusGroupId(MediaSessionImpl* session) { - // Allow the media session to override the group id. - if (session->audio_focus_group_id() != base::UnguessableToken::Null()) - return session->audio_focus_group_id(); - - // If we are on Chrome OS, then use a shared audio focus group id for the - // whole browser. This will mean that tabs will share audio focus. -#if defined(OS_CHROMEOS) +static const base::UnguessableToken& GetBrowserGroupId() { static const base::NoDestructor<base::UnguessableToken> token( base::UnguessableToken::Create()); return *token; -#else - return base::UnguessableToken::Create(); -#endif } // AudioFocusDelegateDefault is the default implementation of @@ -113,7 +102,9 @@ audio_focus_ptr_->RequestGroupedAudioFocus( mojo::MakeRequest(&request_client_ptr_), std::move(media_session), session_info_.Clone(), audio_focus_type, - GetAudioFocusGroupId(media_session_), + media_session_->audio_focus_group_id() == base::UnguessableToken::Null() + ? GetBrowserGroupId() + : media_session_->audio_focus_group_id(), base::BindOnce(&AudioFocusDelegateDefault::FinishAudioFocusRequest, base::Unretained(this), audio_focus_type)); }
diff --git a/content/browser/media/session/audio_focus_delegate_default_browsertest.cc b/content/browser/media/session/audio_focus_delegate_default_browsertest.cc index 619b865..45cdfc24 100644 --- a/content/browser/media/session/audio_focus_delegate_default_browsertest.cc +++ b/content/browser/media/session/audio_focus_delegate_default_browsertest.cc
@@ -4,7 +4,6 @@ #include "base/command_line.h" #include "base/unguessable_token.h" -#include "build/build_config.h" #include "content/browser/media/session/media_session_impl.h" #include "content/browser/media/session/mock_media_session_player_observer.h" #include "content/public/common/service_manager_connection.h" @@ -26,14 +25,6 @@ const char kExpectedSourceName[] = "web"; -bool IsBrowserAudioFocusGroupingEnabled() { -#if defined(OS_CHROMEOS) - return true; -#else - return false; -#endif -} - } // namespace class AudioFocusDelegateDefaultBrowserTest : public ContentBrowserTest { @@ -115,7 +106,7 @@ media_session::test::MockMediaSessionMojoObserver observer( *media_session); observer.WaitForState( - use_separate_group_id || !IsBrowserAudioFocusGroupingEnabled() + use_separate_group_id ? media_session::mojom::MediaSessionInfo::SessionState::kSuspended : media_session::mojom::MediaSessionInfo::SessionState::kActive); }
diff --git a/content/browser/media/session/media_session_browsertest.cc b/content/browser/media/session/media_session_browsertest.cc index b6c4fcb..1d43cc1 100644 --- a/content/browser/media/session/media_session_browsertest.cc +++ b/content/browser/media/session/media_session_browsertest.cc
@@ -16,6 +16,7 @@ #include "content/shell/browser/shell.h" #include "media/base/media_switches.h" #include "services/media_session/public/cpp/switches.h" +#include "services/media_session/public/cpp/test/audio_focus_test_util.h" namespace content { @@ -187,15 +188,18 @@ ASSERT_NE(nullptr, media_session); StartPlaybackAndWait(shell(), "long-video"); - EXPECT_FALSE(media_session->IsControllable()); + EXPECT_FALSE(media_session::test::GetMediaSessionInfoSync(media_session) + ->is_controllable); // Unmute the web contents and the player should be created. shell()->web_contents()->SetAudioMuted(false); - EXPECT_TRUE(media_session->IsControllable()); + EXPECT_TRUE(media_session::test::GetMediaSessionInfoSync(media_session) + ->is_controllable); // Now mute it again and the player should be removed. shell()->web_contents()->SetAudioMuted(true); - EXPECT_FALSE(media_session->IsControllable()); + EXPECT_FALSE(media_session::test::GetMediaSessionInfoSync(media_session) + ->is_controllable); } #if !defined(OS_ANDROID)
diff --git a/content/browser/media/session/media_session_impl.h b/content/browser/media/session/media_session_impl.h index 6ee665e..ce0f41c 100644 --- a/content/browser/media/session/media_session_impl.h +++ b/content/browser/media/session/media_session_impl.h
@@ -171,6 +171,13 @@ // Returns information about the MediaSession. media_session::mojom::MediaSessionInfoPtr GetMediaSessionInfoSync(); + // Returns if the session can be controlled by the user. + CONTENT_EXPORT bool IsControllable() const; + + // Compute if the actual playback state is paused by combining the + // MediaSessionService declared state and guessed state (audio_focus_state_). + CONTENT_EXPORT bool IsActuallyPaused() const; + // MediaSession overrides --------------------------------------------------- // Resume the media session. @@ -184,13 +191,6 @@ // Seek the media session. CONTENT_EXPORT void Seek(base::TimeDelta seek_time) override; - // Returns if the session can be controlled by the user. - CONTENT_EXPORT bool IsControllable() const override; - - // Compute if the actual playback state is paused by combining the - // MediaSessionService declared state and guessed state (audio_focus_state_). - CONTENT_EXPORT bool IsActuallyPaused() const override; - // Called when a MediaSessionAction is received. The action will be forwarded // to blink::MediaSession corresponding to the current routed service. void DidReceiveAction(
diff --git a/content/browser/network_service_client_unittest.cc b/content/browser/network_service_client_unittest.cc index 5d6e02160..de2c0047 100644 --- a/content/browser/network_service_client_unittest.cc +++ b/content/browser/network_service_client_unittest.cc
@@ -13,6 +13,7 @@ #include "base/test/test_file_util.h" #include "build/build_config.h" #include "content/browser/child_process_security_policy_impl.h" +#include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" namespace content { @@ -76,7 +77,7 @@ } protected: - base::test::ScopedTaskEnvironment scoped_task_environment_; + TestBrowserThreadBundle scoped_task_environment_; network::mojom::NetworkServiceClientPtr client_ptr_; NetworkServiceClient client_; base::ScopedTempDir temp_dir_;
diff --git a/content/browser/payments/payment_app_content_unittest_base.cc b/content/browser/payments/payment_app_content_unittest_base.cc index a6bacfc..b53ff7f 100644 --- a/content/browser/payments/payment_app_content_unittest_base.cc +++ b/content/browser/payments/payment_app_content_unittest_base.cc
@@ -15,12 +15,12 @@ #include "content/browser/service_worker/embedded_worker_test_helper.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/storage_partition_impl.h" -#include "content/common/service_worker/service_worker.mojom.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_browser_thread_bundle.h" #include "mojo/public/cpp/bindings/associated_interface_ptr.h" #include "mojo/public/cpp/bindings/interface_request.h" #include "third_party/blink/public/common/service_worker/service_worker_status_code.h" +#include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h" namespace content { @@ -66,7 +66,7 @@ const GURL& scope, const GURL& script_url, bool pause_after_download, - mojom::ServiceWorkerRequest service_worker_request, + blink::mojom::ServiceWorkerRequest service_worker_request, blink::mojom::ControllerServiceWorkerRequest controller_request, mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host, mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info, @@ -86,7 +86,7 @@ void OnPaymentRequestEvent( payments::mojom::PaymentRequestEventDataPtr event_data, payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchPaymentRequestEventCallback callback) + blink::mojom::ServiceWorker::DispatchPaymentRequestEventCallback callback) override { if (respond_payment_request_immediately) { EmbeddedWorkerTestHelper::OnPaymentRequestEvent( @@ -102,7 +102,7 @@ void OnCanMakePaymentEvent( payments::mojom::CanMakePaymentEventDataPtr event_data, payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchCanMakePaymentEventCallback callback) + blink::mojom::ServiceWorker::DispatchCanMakePaymentEventCallback callback) override { EmbeddedWorkerTestHelper::OnCanMakePaymentEvent( std::move(event_data), std::move(response_callback), @@ -111,7 +111,7 @@ void OnAbortPaymentEvent( payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchCanMakePaymentEventCallback callback) + blink::mojom::ServiceWorker::DispatchCanMakePaymentEventCallback callback) override { EmbeddedWorkerTestHelper::OnAbortPaymentEvent(std::move(response_callback), std::move(callback));
diff --git a/content/browser/push_messaging/push_messaging_router.cc b/content/browser/push_messaging/push_messaging_router.cc index 5734e17..ede879d 100644 --- a/content/browser/push_messaging/push_messaging_router.cc +++ b/content/browser/push_messaging/push_messaging_router.cc
@@ -123,7 +123,7 @@ ServiceWorkerMetrics::EventType::PUSH, base::BindOnce(&PushMessagingRouter::DeliverMessageEnd, deliver_message_callback, service_worker_registration), - base::TimeDelta::FromSeconds(mojom::kPushEventTimeoutSeconds), + base::TimeDelta::FromSeconds(blink::mojom::kPushEventTimeoutSeconds), ServiceWorkerVersion::KILL_ON_TIMEOUT); service_worker->endpoint()->DispatchPushEvent(
diff --git a/content/browser/renderer_host/input/touch_action_filter.cc b/content/browser/renderer_host/input/touch_action_filter.cc index 1a6c79f7..7659eaf 100644 --- a/content/browser/renderer_host/input/touch_action_filter.cc +++ b/content/browser/renderer_host/input/touch_action_filter.cc
@@ -7,6 +7,7 @@ #include <math.h> #include "base/debug/crash_logging.h" +#include "base/debug/dump_without_crashing.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "base/strings/string_number_conversions.h" @@ -139,6 +140,13 @@ base::Optional<cc::TouchAction> touch_action = active_touch_action_.has_value() ? active_touch_action_ : white_listed_touch_action_; + if (compositor_touch_action_enabled_ && !touch_action.has_value()) { + static auto* crash_key = base::debug::AllocateCrashKeyString( + "scroll-gestures", base::debug::CrashKeySize::Size256); + base::debug::SetCrashKeyString(crash_key, gesture_sequence_); + base::debug::DumpWithoutCrashing(); + gesture_sequence_.clear(); + } // Filter for allowable touch actions first (eg. before the TouchEventQueue // can decide to send a touch cancel event). @@ -153,8 +161,8 @@ touch_action = cc::kTouchActionAuto; } } + gesture_sequence_.append("B"); if (!compositor_touch_action_enabled_) { - gesture_sequence_.append("B"); if (!active_touch_action_.has_value()) { static auto* crash_key = base::debug::AllocateCrashKeyString( "scrollbegin-gestures", base::debug::CrashKeySize::Size256); @@ -187,8 +195,8 @@ return FilterGestureEventResult::kFilterGestureEventFiltered; } + gesture_sequence_.append("U"); if (!compositor_touch_action_enabled_) - gesture_sequence_.append("U"); // Scrolls restricted to a specific axis shouldn't permit movement // in the perpendicular axis. // @@ -257,8 +265,7 @@ (touch_action.value() & cc::kTouchActionPinchZoom) == 0; FALLTHROUGH; case WebInputEvent::kGesturePinchUpdate: - if (!compositor_touch_action_enabled_) - gesture_sequence_.append("P"); + gesture_sequence_.append("P"); return drop_pinch_events_ ? FilterGestureEventResult::kFilterGestureEventFiltered : FilterGestureEventResult::kFilterGestureEventAllowed; @@ -277,8 +284,7 @@ // assumption here at least to avoid introducing new bugs in future. case WebInputEvent::kGestureDoubleTap: gesture_sequence_in_progress_ = false; - if (!compositor_touch_action_enabled_) - gesture_sequence_.append("D"); + gesture_sequence_.append("D"); DCHECK_EQ(1, gesture_event->data.tap.tap_count); if (!allow_current_double_tap_event_) { gesture_event->SetType(WebInputEvent::kGestureTap); @@ -290,8 +296,8 @@ // If double tap is disabled, there's no reason for the tap delay. case WebInputEvent::kGestureTapUnconfirmed: { DCHECK_EQ(1, gesture_event->data.tap.tap_count); + gesture_sequence_.append("C"); if (!compositor_touch_action_enabled_) { - gesture_sequence_.append("C"); if (!active_touch_action_.has_value()) { static auto* crash_key = base::debug::AllocateCrashKeyString( "tapunconfirmed-gestures", base::debug::CrashKeySize::Size256); @@ -310,8 +316,7 @@ case WebInputEvent::kGestureTap: gesture_sequence_in_progress_ = false; - if (!compositor_touch_action_enabled_) - gesture_sequence_.append("A"); + gesture_sequence_.append("A"); if (drop_current_tap_ending_event_) { drop_current_tap_ending_event_ = false; return FilterGestureEventResult::kFilterGestureEventFiltered; @@ -319,8 +324,7 @@ break; case WebInputEvent::kGestureTapCancel: - if (!compositor_touch_action_enabled_) - gesture_sequence_.append("K"); + gesture_sequence_.append("K"); if (drop_current_tap_ending_event_) { drop_current_tap_ending_event_ = false; return FilterGestureEventResult::kFilterGestureEventFiltered; @@ -334,14 +338,12 @@ if (num_of_active_touches_ <= 0) SetTouchAction(cc::kTouchActionAuto); active_touch_action_ = allowed_touch_action_; - if (!compositor_touch_action_enabled_) { - if (active_touch_action_.has_value()) - gesture_sequence_.append("OY"); - else - gesture_sequence_.append("ON"); - gesture_sequence_.append( - base::NumberToString(gesture_event->unique_touch_event_id)); - } + if (active_touch_action_.has_value()) + gesture_sequence_.append("OY"); + else + gesture_sequence_.append("ON"); + gesture_sequence_.append( + base::NumberToString(gesture_event->unique_touch_event_id)); DCHECK(!drop_current_tap_ending_event_); break;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 0b3b194..a58bdc3 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -3028,6 +3028,7 @@ switches::kEnableUseZoomForDSF, switches::kEnableViewport, switches::kEnableVtune, + switches::kEnableWebBluetoothScanning, switches::kEnableWebGL2ComputeContext, switches::kEnableWebGLDraftExtensions, switches::kEnableWebGLImageChromium,
diff --git a/content/browser/sandbox_host_linux.cc b/content/browser/sandbox_host_linux.cc index 2f89027..db3b884c 100644 --- a/content/browser/sandbox_host_linux.cc +++ b/content/browser/sandbox_host_linux.cc
@@ -64,6 +64,10 @@ if (IGNORE_EINTR(close(child_socket_)) < 0) PLOG(ERROR) << "close"; + // TODO(gab): We might be able to just delete this destructor: + // https://chromium-review.googlesource.com/c/chromium/src/+/1378683 + base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope + allow_thread_join_on_shutdown; ipc_thread_->Join(); } }
diff --git a/content/browser/service_worker/embedded_worker_instance.h b/content/browser/service_worker/embedded_worker_instance.h index 8285bd89..b456bf3 100644 --- a/content/browser/service_worker/embedded_worker_instance.h +++ b/content/browser/service_worker/embedded_worker_instance.h
@@ -25,7 +25,6 @@ #include "content/browser/service_worker/service_worker_metrics.h" #include "content/common/content_export.h" #include "content/common/service_worker/embedded_worker.mojom.h" -#include "content/common/service_worker/service_worker.mojom.h" #include "mojo/public/cpp/bindings/associated_binding.h" #include "third_party/blink/public/common/service_worker/service_worker_status_code.h" #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom.h"
diff --git a/content/browser/service_worker/embedded_worker_instance_unittest.cc b/content/browser/service_worker/embedded_worker_instance_unittest.cc index ee11f7b..243ae63 100644 --- a/content/browser/service_worker/embedded_worker_instance_unittest.cc +++ b/content/browser/service_worker/embedded_worker_instance_unittest.cc
@@ -22,7 +22,6 @@ #include "content/browser/service_worker/service_worker_test_utils.h" #include "content/browser/service_worker/service_worker_version.h" #include "content/common/service_worker/embedded_worker.mojom.h" -#include "content/common/service_worker/service_worker.mojom.h" #include "content/public/common/child_process_host.h" #include "content/public/common/content_switches.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -179,7 +178,7 @@ return provider_info; } - mojom::ServiceWorkerRequest CreateServiceWorker() { + blink::mojom::ServiceWorkerRequest CreateServiceWorker() { service_workers_.emplace_back(); return mojo::MakeRequest(&service_workers_.back()); } @@ -219,7 +218,7 @@ } // Mojo endpoints. - std::vector<mojom::ServiceWorkerPtr> service_workers_; + std::vector<blink::mojom::ServiceWorkerPtr> service_workers_; std::vector<blink::mojom::ControllerServiceWorkerPtr> controllers_; std::vector<blink::mojom::ServiceWorkerInstalledScriptsManagerPtr> installed_scripts_managers_; @@ -248,7 +247,7 @@ const GURL& scope, const GURL& script_url, bool pause_after_download, - mojom::ServiceWorkerRequest service_worker_request, + blink::mojom::ServiceWorkerRequest service_worker_request, blink::mojom::ControllerServiceWorkerRequest controller_request, mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host, mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info, @@ -816,7 +815,7 @@ const GURL& scope, const GURL& script_url, bool pause_after_download, - mojom::ServiceWorkerRequest service_worker_request, + blink::mojom::ServiceWorkerRequest service_worker_request, blink::mojom::ControllerServiceWorkerRequest controller_request, mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host, mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
diff --git a/content/browser/service_worker/embedded_worker_test_helper.cc b/content/browser/service_worker/embedded_worker_test_helper.cc index 0ca25204..c82717c 100644 --- a/content/browser/service_worker/embedded_worker_test_helper.cc +++ b/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -23,7 +23,6 @@ #include "content/browser/service_worker/service_worker_test_utils.h" #include "content/common/background_fetch/background_fetch_types.h" #include "content/common/renderer.mojom.h" -#include "content/common/service_worker/service_worker.mojom.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_browser_context.h" #include "mojo/public/cpp/bindings/associated_binding_set.h" @@ -35,6 +34,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/service_worker/service_worker_utils.h" #include "third_party/blink/public/mojom/fetch/fetch_api_response.mojom.h" +#include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h" namespace content { @@ -43,7 +43,7 @@ void OnFetchEventCommon( blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) { + blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) { auto response = blink::mojom::FetchAPIResponse::New(); response->status_code = 200; response->status_text = "OK"; @@ -171,11 +171,11 @@ } class EmbeddedWorkerTestHelper::MockServiceWorker - : public mojom::ServiceWorker { + : public blink::mojom::ServiceWorker { public: static void Create(const base::WeakPtr<EmbeddedWorkerTestHelper>& helper, int embedded_worker_id, - mojom::ServiceWorkerRequest request) { + blink::mojom::ServiceWorkerRequest request) { mojo::MakeStrongBinding( std::make_unique<MockServiceWorker>(helper, embedded_worker_id), std::move(request)); @@ -337,7 +337,7 @@ } void DispatchExtendableMessageEvent( - mojom::ExtendableMessageEventPtr event, + blink::mojom::ExtendableMessageEventPtr event, DispatchExtendableMessageEventCallback callback) override { if (!helper_) return; @@ -346,7 +346,7 @@ } void DispatchExtendableMessageEventWithCustomTimeout( - mojom::ExtendableMessageEventPtr event, + blink::mojom::ExtendableMessageEventPtr event, base::TimeDelta timeout, DispatchExtendableMessageEventWithCustomTimeoutCallback callback) override { @@ -534,7 +534,7 @@ const GURL& scope, const GURL& script_url, bool pause_after_download, - mojom::ServiceWorkerRequest service_worker_request, + blink::mojom::ServiceWorkerRequest service_worker_request, blink::mojom::ControllerServiceWorkerRequest controller_request, mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host, mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info, @@ -582,32 +582,35 @@ } void EmbeddedWorkerTestHelper::OnActivateEvent( - mojom::ServiceWorker::DispatchActivateEventCallback callback) { + blink::mojom::ServiceWorker::DispatchActivateEventCallback callback) { dispatched_events()->push_back(Event::Activate); std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED); } void EmbeddedWorkerTestHelper::OnBackgroundFetchAbortEvent( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback callback) { + blink::mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback + callback) { std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED); } void EmbeddedWorkerTestHelper::OnBackgroundFetchClickEvent( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback callback) { + blink::mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback + callback) { std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED); } void EmbeddedWorkerTestHelper::OnBackgroundFetchFailEvent( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback callback) { + blink::mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback + callback) { std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED); } void EmbeddedWorkerTestHelper::OnBackgroundFetchSuccessEvent( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback + blink::mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback callback) { std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED); } @@ -615,18 +618,19 @@ void EmbeddedWorkerTestHelper::OnCookieChangeEvent( const net::CanonicalCookie& cookie, ::network::mojom::CookieChangeCause cause, - mojom::ServiceWorker::DispatchCookieChangeEventCallback callback) { + blink::mojom::ServiceWorker::DispatchCookieChangeEventCallback callback) { std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED); } void EmbeddedWorkerTestHelper::OnExtendableMessageEvent( - mojom::ExtendableMessageEventPtr event, - mojom::ServiceWorker::DispatchExtendableMessageEventCallback callback) { + blink::mojom::ExtendableMessageEventPtr event, + blink::mojom::ServiceWorker::DispatchExtendableMessageEventCallback + callback) { std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED); } void EmbeddedWorkerTestHelper::OnInstallEvent( - mojom::ServiceWorker::DispatchInstallEventCallback callback) { + blink::mojom::ServiceWorker::DispatchInstallEventCallback callback) { dispatched_events()->push_back(Event::Install); std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED, true /* has_fetch_handler */); @@ -637,14 +641,14 @@ blink::mojom::FetchAPIRequestPtr /* request */, blink::mojom::FetchEventPreloadHandlePtr /* preload_handle */, blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) { + blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) { // TODO(falken): In-line common into here. OnFetchEventCommon(std::move(response_callback), std::move(finish_callback)); } void EmbeddedWorkerTestHelper::OnPushEvent( base::Optional<std::string> payload, - mojom::ServiceWorker::DispatchPushEventCallback callback) { + blink::mojom::ServiceWorker::DispatchPushEventCallback callback) { std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED); } @@ -653,20 +657,22 @@ const blink::PlatformNotificationData& notification_data, int action_index, const base::Optional<base::string16>& reply, - mojom::ServiceWorker::DispatchNotificationClickEventCallback callback) { + blink::mojom::ServiceWorker::DispatchNotificationClickEventCallback + callback) { std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED); } void EmbeddedWorkerTestHelper::OnNotificationCloseEvent( const std::string& notification_id, const blink::PlatformNotificationData& notification_data, - mojom::ServiceWorker::DispatchNotificationCloseEventCallback callback) { + blink::mojom::ServiceWorker::DispatchNotificationCloseEventCallback + callback) { std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED); } void EmbeddedWorkerTestHelper::OnAbortPaymentEvent( payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchAbortPaymentEventCallback callback) { + blink::mojom::ServiceWorker::DispatchAbortPaymentEventCallback callback) { response_callback->OnResponseForAbortPayment(true); std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED); } @@ -674,7 +680,7 @@ void EmbeddedWorkerTestHelper::OnCanMakePaymentEvent( payments::mojom::CanMakePaymentEventDataPtr event_data, payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchCanMakePaymentEventCallback callback) { + blink::mojom::ServiceWorker::DispatchCanMakePaymentEventCallback callback) { bool can_make_payment = false; for (const auto& method_data : event_data->method_data) { if (method_data->supported_method == "test-method") { @@ -689,7 +695,7 @@ void EmbeddedWorkerTestHelper::OnPaymentRequestEvent( payments::mojom::PaymentRequestEventDataPtr event_data, payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchPaymentRequestEventCallback callback) { + blink::mojom::ServiceWorker::DispatchPaymentRequestEventCallback callback) { response_callback->OnResponseForPaymentRequest( payments::mojom::PaymentHandlerResponse::New()); std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED); @@ -849,7 +855,7 @@ } void EmbeddedWorkerTestHelper::OnActivateEventStub( - mojom::ServiceWorker::DispatchActivateEventCallback callback) { + blink::mojom::ServiceWorker::DispatchActivateEventCallback callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnActivateEvent, AsWeakPtr(), std::move(callback))); @@ -857,7 +863,8 @@ void EmbeddedWorkerTestHelper::OnBackgroundFetchAbortEventStub( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback callback) { + blink::mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback + callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchAbortEvent, @@ -867,7 +874,8 @@ void EmbeddedWorkerTestHelper::OnBackgroundFetchClickEventStub( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback callback) { + blink::mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback + callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchClickEvent, @@ -877,7 +885,8 @@ void EmbeddedWorkerTestHelper::OnBackgroundFetchFailEventStub( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback callback) { + blink::mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback + callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchFailEvent, @@ -887,7 +896,7 @@ void EmbeddedWorkerTestHelper::OnBackgroundFetchSuccessEventStub( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback + blink::mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, @@ -899,7 +908,7 @@ void EmbeddedWorkerTestHelper::OnCookieChangeEventStub( const net::CanonicalCookie& cookie, ::network::mojom::CookieChangeCause cause, - mojom::ServiceWorker::DispatchCookieChangeEventCallback callback) { + blink::mojom::ServiceWorker::DispatchCookieChangeEventCallback callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnCookieChangeEvent, @@ -907,8 +916,9 @@ } void EmbeddedWorkerTestHelper::OnExtendableMessageEventStub( - mojom::ExtendableMessageEventPtr event, - mojom::ServiceWorker::DispatchExtendableMessageEventCallback callback) { + blink::mojom::ExtendableMessageEventPtr event, + blink::mojom::ServiceWorker::DispatchExtendableMessageEventCallback + callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnExtendableMessageEvent, @@ -916,7 +926,7 @@ } void EmbeddedWorkerTestHelper::OnInstallEventStub( - mojom::ServiceWorker::DispatchInstallEventCallback callback) { + blink::mojom::ServiceWorker::DispatchInstallEventCallback callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnInstallEvent, AsWeakPtr(), std::move(callback))); @@ -927,7 +937,7 @@ blink::mojom::FetchAPIRequestPtr request, blink::mojom::FetchEventPreloadHandlePtr preload_handle, blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) { + blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnFetchEvent, AsWeakPtr(), @@ -941,7 +951,8 @@ const blink::PlatformNotificationData& notification_data, int action_index, const base::Optional<base::string16>& reply, - mojom::ServiceWorker::DispatchNotificationClickEventCallback callback) { + blink::mojom::ServiceWorker::DispatchNotificationClickEventCallback + callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnNotificationClickEvent, @@ -952,7 +963,8 @@ void EmbeddedWorkerTestHelper::OnNotificationCloseEventStub( const std::string& notification_id, const blink::PlatformNotificationData& notification_data, - mojom::ServiceWorker::DispatchNotificationCloseEventCallback callback) { + blink::mojom::ServiceWorker::DispatchNotificationCloseEventCallback + callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnNotificationCloseEvent, @@ -962,7 +974,7 @@ void EmbeddedWorkerTestHelper::OnPushEventStub( base::Optional<std::string> payload, - mojom::ServiceWorker::DispatchPushEventCallback callback) { + blink::mojom::ServiceWorker::DispatchPushEventCallback callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnPushEvent, AsWeakPtr(), @@ -971,7 +983,7 @@ void EmbeddedWorkerTestHelper::OnAbortPaymentEventStub( payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchAbortPaymentEventCallback callback) { + blink::mojom::ServiceWorker::DispatchAbortPaymentEventCallback callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnAbortPaymentEvent, AsWeakPtr(), std::move(response_callback), @@ -981,7 +993,7 @@ void EmbeddedWorkerTestHelper::OnCanMakePaymentEventStub( payments::mojom::CanMakePaymentEventDataPtr event_data, payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchCanMakePaymentEventCallback callback) { + blink::mojom::ServiceWorker::DispatchCanMakePaymentEventCallback callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnCanMakePaymentEvent, @@ -992,7 +1004,7 @@ void EmbeddedWorkerTestHelper::OnPaymentRequestEventStub( payments::mojom::PaymentRequestEventDataPtr event_data, payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchPaymentRequestEventCallback callback) { + blink::mojom::ServiceWorker::DispatchPaymentRequestEventCallback callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnPaymentRequestEvent,
diff --git a/content/browser/service_worker/embedded_worker_test_helper.h b/content/browser/service_worker/embedded_worker_test_helper.h index 00efb09..cb6d0deb 100644 --- a/content/browser/service_worker/embedded_worker_test_helper.h +++ b/content/browser/service_worker/embedded_worker_test_helper.h
@@ -20,7 +20,6 @@ #include "content/browser/service_worker/service_worker_test_utils.h" #include "content/browser/url_loader_factory_getter.h" #include "content/common/service_worker/embedded_worker.mojom.h" -#include "content/common/service_worker/service_worker.mojom.h" #include "mojo/public/cpp/bindings/binding.h" #include "net/cookies/cookie_change_dispatcher.h" #include "net/http/http_response_info.h" @@ -158,7 +157,7 @@ const GURL& scope, const GURL& script_url, bool pause_after_download, - mojom::ServiceWorkerRequest service_worker_request, + blink::mojom::ServiceWorkerRequest service_worker_request, blink::mojom::ControllerServiceWorkerRequest controller_request, mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host, mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info, @@ -172,59 +171,67 @@ // On*Event handlers. By default they just return success via // SimulateSendReplyToBrowser. virtual void OnActivateEvent( - mojom::ServiceWorker::DispatchActivateEventCallback callback); + blink::mojom::ServiceWorker::DispatchActivateEventCallback callback); virtual void OnBackgroundFetchAbortEvent( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback callback); + blink::mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback + callback); virtual void OnBackgroundFetchClickEvent( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback callback); + blink::mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback + callback); virtual void OnBackgroundFetchFailEvent( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback callback); + blink::mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback + callback); virtual void OnBackgroundFetchSuccessEvent( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback + blink::mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback callback); virtual void OnCookieChangeEvent( const net::CanonicalCookie& cookie, ::network::mojom::CookieChangeCause cause, - mojom::ServiceWorker::DispatchCookieChangeEventCallback callback); + blink::mojom::ServiceWorker::DispatchCookieChangeEventCallback callback); virtual void OnExtendableMessageEvent( - mojom::ExtendableMessageEventPtr event, - mojom::ServiceWorker::DispatchExtendableMessageEventCallback callback); + blink::mojom::ExtendableMessageEventPtr event, + blink::mojom::ServiceWorker::DispatchExtendableMessageEventCallback + callback); virtual void OnInstallEvent( - mojom::ServiceWorker::DispatchInstallEventCallback callback); + blink::mojom::ServiceWorker::DispatchInstallEventCallback callback); virtual void OnFetchEvent( int embedded_worker_id, blink::mojom::FetchAPIRequestPtr request, blink::mojom::FetchEventPreloadHandlePtr preload_handle, blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchFetchEventCallback finish_callback); + blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback); virtual void OnNotificationClickEvent( const std::string& notification_id, const blink::PlatformNotificationData& notification_data, int action_index, const base::Optional<base::string16>& reply, - mojom::ServiceWorker::DispatchNotificationClickEventCallback callback); + blink::mojom::ServiceWorker::DispatchNotificationClickEventCallback + callback); virtual void OnNotificationCloseEvent( const std::string& notification_id, const blink::PlatformNotificationData& notification_data, - mojom::ServiceWorker::DispatchNotificationCloseEventCallback callback); + blink::mojom::ServiceWorker::DispatchNotificationCloseEventCallback + callback); virtual void OnPushEvent( base::Optional<std::string> payload, - mojom::ServiceWorker::DispatchPushEventCallback callback); + blink::mojom::ServiceWorker::DispatchPushEventCallback callback); virtual void OnAbortPaymentEvent( payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchAbortPaymentEventCallback callback); + blink::mojom::ServiceWorker::DispatchAbortPaymentEventCallback callback); virtual void OnCanMakePaymentEvent( payments::mojom::CanMakePaymentEventDataPtr data, payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchCanMakePaymentEventCallback callback); + blink::mojom::ServiceWorker::DispatchCanMakePaymentEventCallback + callback); virtual void OnPaymentRequestEvent( payments::mojom::PaymentRequestEventDataPtr data, payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchPaymentRequestEventCallback callback); + blink::mojom::ServiceWorker::DispatchPaymentRequestEventCallback + callback); virtual void OnSetIdleTimerDelayToZero(int embedded_worker_id); // These functions simulate making Mojo calls to the browser. @@ -266,59 +273,67 @@ void OnResumeAfterDownloadStub(int embedded_worker_id); void OnStopWorkerStub(int embedded_worker_id); void OnActivateEventStub( - mojom::ServiceWorker::DispatchActivateEventCallback callback); + blink::mojom::ServiceWorker::DispatchActivateEventCallback callback); void OnBackgroundFetchAbortEventStub( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback callback); + blink::mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback + callback); void OnBackgroundFetchClickEventStub( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback callback); + blink::mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback + callback); void OnBackgroundFetchFailEventStub( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback callback); + blink::mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback + callback); void OnBackgroundFetchSuccessEventStub( blink::mojom::BackgroundFetchRegistrationPtr registration, - mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback + blink::mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback callback); void OnCookieChangeEventStub( const net::CanonicalCookie& cookie, ::network::mojom::CookieChangeCause cause, - mojom::ServiceWorker::DispatchCookieChangeEventCallback callback); + blink::mojom::ServiceWorker::DispatchCookieChangeEventCallback callback); void OnExtendableMessageEventStub( - mojom::ExtendableMessageEventPtr event, - mojom::ServiceWorker::DispatchExtendableMessageEventCallback callback); + blink::mojom::ExtendableMessageEventPtr event, + blink::mojom::ServiceWorker::DispatchExtendableMessageEventCallback + callback); void OnInstallEventStub( - mojom::ServiceWorker::DispatchInstallEventCallback callback); + blink::mojom::ServiceWorker::DispatchInstallEventCallback callback); void OnFetchEventStub( int embedded_worker_id, blink::mojom::FetchAPIRequestPtr request, blink::mojom::FetchEventPreloadHandlePtr preload_handle, blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchFetchEventCallback finish_callback); + blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback); void OnNotificationClickEventStub( const std::string& notification_id, const blink::PlatformNotificationData& notification_data, int action_index, const base::Optional<base::string16>& reply, - mojom::ServiceWorker::DispatchNotificationClickEventCallback callback); + blink::mojom::ServiceWorker::DispatchNotificationClickEventCallback + callback); void OnNotificationCloseEventStub( const std::string& notification_id, const blink::PlatformNotificationData& notification_data, - mojom::ServiceWorker::DispatchNotificationCloseEventCallback callback); + blink::mojom::ServiceWorker::DispatchNotificationCloseEventCallback + callback); void OnPushEventStub( base::Optional<std::string> payload, - mojom::ServiceWorker::DispatchPushEventCallback callback); + blink::mojom::ServiceWorker::DispatchPushEventCallback callback); void OnAbortPaymentEventStub( payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchAbortPaymentEventCallback callback); + blink::mojom::ServiceWorker::DispatchAbortPaymentEventCallback callback); void OnCanMakePaymentEventStub( payments::mojom::CanMakePaymentEventDataPtr data, payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchCanMakePaymentEventCallback callback); + blink::mojom::ServiceWorker::DispatchCanMakePaymentEventCallback + callback); void OnPaymentRequestEventStub( payments::mojom::PaymentRequestEventDataPtr data, payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchPaymentRequestEventCallback callback); + blink::mojom::ServiceWorker::DispatchPaymentRequestEventCallback + callback); std::unique_ptr<TestBrowserContext> browser_context_; std::unique_ptr<MockRenderProcessHost> render_process_host_;
diff --git a/content/browser/service_worker/service_worker_context_unittest.cc b/content/browser/service_worker/service_worker_context_unittest.cc index c645c83..9d67ef6d 100644 --- a/content/browser/service_worker/service_worker_context_unittest.cc +++ b/content/browser/service_worker/service_worker_context_unittest.cc
@@ -89,8 +89,8 @@ public: RejectInstallTestHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {} - void OnInstallEvent( - mojom::ServiceWorker::DispatchInstallEventCallback callback) override { + void OnInstallEvent(blink::mojom::ServiceWorker::DispatchInstallEventCallback + callback) override { dispatched_events()->push_back(Event::Install); std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::REJECTED, true /* has_fetch_handler */); @@ -102,7 +102,8 @@ RejectActivateTestHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {} void OnActivateEvent( - mojom::ServiceWorker::DispatchActivateEventCallback callback) override { + blink::mojom::ServiceWorker::DispatchActivateEventCallback callback) + override { dispatched_events()->push_back(Event::Activate); std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::REJECTED); }
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc index 56d569ba..ab8738e 100644 --- a/content/browser/service_worker/service_worker_context_wrapper.cc +++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -535,7 +535,8 @@ base::TimeDelta::FromDays(kActiveWorkerTimeoutDays), ServiceWorkerVersion::CONTINUE_ON_TIMEOUT); - mojom::ExtendableMessageEventPtr event = mojom::ExtendableMessageEvent::New(); + blink::mojom::ExtendableMessageEventPtr event = + blink::mojom::ExtendableMessageEvent::New(); event->message = std::move(message); event->source_origin = url::Origin::Create(source_origin); event->source_info_for_service_worker =
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc index 049da64..2caa589 100644 --- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc +++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -25,7 +25,6 @@ #include "content/browser/service_worker/service_worker_metrics.h" #include "content/browser/service_worker/service_worker_version.h" #include "content/browser/url_loader_factory_getter.h" -#include "content/common/service_worker/service_worker.mojom.h" #include "content/common/service_worker/service_worker_types.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h"
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.h b/content/browser/service_worker/service_worker_fetch_dispatcher.h index af8c31c..63e1fdb 100644 --- a/content/browser/service_worker/service_worker_fetch_dispatcher.h +++ b/content/browser/service_worker/service_worker_fetch_dispatcher.h
@@ -15,7 +15,6 @@ #include "base/time/time.h" #include "content/browser/service_worker/service_worker_metrics.h" #include "content/common/content_export.h" -#include "content/common/service_worker/service_worker.mojom.h" #include "content/public/common/resource_type.h" #include "mojo/public/cpp/system/data_pipe.h" #include "net/log/net_log_with_source.h"
diff --git a/content/browser/service_worker/service_worker_job_unittest.cc b/content/browser/service_worker/service_worker_job_unittest.cc index 33f4459d..22c81515 100644 --- a/content/browser/service_worker/service_worker_job_unittest.cc +++ b/content/browser/service_worker/service_worker_job_unittest.cc
@@ -500,7 +500,7 @@ const GURL& scope, const GURL& script_url, bool pause_after_download, - mojom::ServiceWorkerRequest service_worker_request, + blink::mojom::ServiceWorkerRequest service_worker_request, blink::mojom::ControllerServiceWorkerRequest controller_request, mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host, mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info, @@ -1008,7 +1008,7 @@ const GURL& scope, const GURL& script, bool pause_after_download, - mojom::ServiceWorkerRequest service_worker_request, + blink::mojom::ServiceWorkerRequest service_worker_request, blink::mojom::ControllerServiceWorkerRequest controller_request, mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host, mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info, @@ -1151,7 +1151,7 @@ const GURL& scope, const GURL& script, bool pause_after_download, - mojom::ServiceWorkerRequest service_worker_request, + blink::mojom::ServiceWorkerRequest service_worker_request, blink::mojom::ControllerServiceWorkerRequest controller_request, mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host, mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info, @@ -1723,15 +1723,16 @@ activate_event_result_( blink::mojom::ServiceWorkerEventStatus::COMPLETED) {} - void OnInstallEvent( - mojom::ServiceWorker::DispatchInstallEventCallback callback) override { + void OnInstallEvent(blink::mojom::ServiceWorker::DispatchInstallEventCallback + callback) override { if (!install_callback_.is_null()) std::move(install_callback_).Run(); std::move(callback).Run(install_event_result_, has_fetch_handler_); } void OnActivateEvent( - mojom::ServiceWorker::DispatchActivateEventCallback callback) override { + blink::mojom::ServiceWorker::DispatchActivateEventCallback callback) + override { std::move(callback).Run(activate_event_result_); }
diff --git a/content/browser/service_worker/service_worker_navigation_loader_unittest.cc b/content/browser/service_worker/service_worker_navigation_loader_unittest.cc index 3d8a2b5..521f764 100644 --- a/content/browser/service_worker/service_worker_navigation_loader_unittest.cc +++ b/content/browser/service_worker/service_worker_navigation_loader_unittest.cc
@@ -16,7 +16,6 @@ #include "content/browser/service_worker/service_worker_registration.h" #include "content/browser/service_worker/service_worker_test_utils.h" #include "content/browser/service_worker/service_worker_version.h" -#include "content/common/service_worker/service_worker.mojom.h" #include "content/common/service_worker/service_worker_utils.h" #include "content/common/single_request_url_loader_factory.h" #include "content/public/test/mock_render_process_host.h" @@ -35,6 +34,7 @@ #include "storage/browser/blob/blob_impl.h" #include "storage/browser/blob/blob_storage_context.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h" @@ -107,7 +107,7 @@ NavigationPreloadLoaderClient( blink::mojom::FetchEventPreloadHandlePtr preload_handle, blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) + blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) : url_loader_(std::move(preload_handle->url_loader)), binding_(this, std::move(preload_handle->url_loader_client_request)), response_callback_(std::move(response_callback)), @@ -171,7 +171,7 @@ // Callbacks that complete Helper::OnFetchEvent(). blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback_; - mojom::ServiceWorker::DispatchFetchEventCallback finish_callback_; + blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback_; DISALLOW_COPY_AND_ASSIGN(NavigationPreloadLoaderClient); }; @@ -278,7 +278,7 @@ blink::mojom::FetchAPIRequestPtr request, blink::mojom::FetchEventPreloadHandlePtr preload_handle, blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) + blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) override { // Basic checks on DispatchFetchEvent parameters. EXPECT_TRUE(request->is_main_resource_load); @@ -334,7 +334,7 @@ SimulateWorkerStopped(embedded_worker_id); // Finish the event by calling |finish_callback|. // This is the Mojo callback for - // mojom::ServiceWorker::DispatchFetchEvent(). + // blink::mojom::ServiceWorker::DispatchFetchEvent(). // If this is not called, Mojo will complain. In production code, // ServiceWorkerContextClient would call this when it aborts all // callbacks after an unexpected stop. @@ -390,7 +390,7 @@ blink::mojom::ServiceWorkerStreamHandlePtr stream_handle_; // For ResponseMode::kEarlyResponse and kDeferredResponse. - mojom::ServiceWorker::DispatchFetchEventCallback finish_callback_; + blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback_; blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback_; // For ResponseMode::kRedirect.
diff --git a/content/browser/service_worker/service_worker_object_host.cc b/content/browser/service_worker/service_worker_object_host.cc index 12627f88..61ba133 100644 --- a/content/browser/service_worker/service_worker_object_host.cc +++ b/content/browser/service_worker/service_worker_object_host.cc
@@ -19,7 +19,7 @@ using StatusCallback = base::OnceCallback<void(blink::ServiceWorkerStatusCode)>; using PrepareExtendableMessageEventCallback = - base::OnceCallback<bool(mojom::ExtendableMessageEventPtr*)>; + base::OnceCallback<bool(blink::mojom::ExtendableMessageEventPtr*)>; void DispatchExtendableMessageEventAfterStartWorker( scoped_refptr<ServiceWorkerVersion> worker, @@ -34,7 +34,8 @@ return; } - mojom::ExtendableMessageEventPtr event = mojom::ExtendableMessageEvent::New(); + blink::mojom::ExtendableMessageEventPtr event = + blink::mojom::ExtendableMessageEvent::New(); event->message = std::move(message); event->source_origin = source_origin; if (!std::move(prepare_callback).Run(&event)) { @@ -80,7 +81,7 @@ base::WeakPtr<ServiceWorkerContextCore> context, int64_t registration_id, blink::mojom::ServiceWorkerClientInfoPtr source_client_info, - mojom::ExtendableMessageEventPtr* event) { + blink::mojom::ExtendableMessageEventPtr* event) { if (!context) { return false; } @@ -108,7 +109,7 @@ scoped_refptr<ServiceWorkerVersion> worker, base::WeakPtr<ServiceWorkerProviderHost> source_service_worker_provider_host, - mojom::ExtendableMessageEventPtr* event) { + blink::mojom::ExtendableMessageEventPtr* event) { // The service worker execution context may have been destroyed by the time we // get here. if (!source_service_worker_provider_host)
diff --git a/content/browser/service_worker/service_worker_object_host_unittest.cc b/content/browser/service_worker/service_worker_object_host_unittest.cc index 151df190..8e3280d 100644 --- a/content/browser/service_worker/service_worker_object_host_unittest.cc +++ b/content/browser/service_worker/service_worker_object_host_unittest.cc
@@ -51,19 +51,19 @@ : EmbeddedWorkerTestHelper(base::FilePath()) {} void OnExtendableMessageEvent( - mojom::ExtendableMessageEventPtr event, - mojom::ServiceWorker::DispatchExtendableMessageEventCallback callback) - override { + blink::mojom::ExtendableMessageEventPtr event, + blink::mojom::ServiceWorker::DispatchExtendableMessageEventCallback + callback) override { events_.push_back(std::move(event)); std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED); } - const std::vector<mojom::ExtendableMessageEventPtr>& events() { + const std::vector<blink::mojom::ExtendableMessageEventPtr>& events() { return events_; } private: - std::vector<mojom::ExtendableMessageEventPtr> events_; + std::vector<blink::mojom::ExtendableMessageEventPtr> events_; }; class FailToStartWorkerTestHelper : public ExtendableMessageEventTestHelper { @@ -76,7 +76,7 @@ const GURL& scope, const GURL& script_url, bool pause_after_download, - mojom::ServiceWorkerRequest service_worker_request, + blink::mojom::ServiceWorkerRequest service_worker_request, blink::mojom::ControllerServiceWorkerRequest controller_request, mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host, mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info, @@ -302,7 +302,7 @@ // should correspond to the pair (|version_->provider_host()|, |version_|), // means it should correspond to |sender_worker_object_host|. EXPECT_EQ(2u, GetBindingsCount(sender_worker_object_host)); - const std::vector<mojom::ExtendableMessageEventPtr>& events = + const std::vector<blink::mojom::ExtendableMessageEventPtr>& events = static_cast<ExtendableMessageEventTestHelper*>(helper_.get())->events(); EXPECT_EQ(1u, events.size()); EXPECT_FALSE(events[0]->source_info_for_client); @@ -362,7 +362,7 @@ // The dispatched ExtendableMessageEvent should be kept in // ExtendableMessageEventTestHelper, and its source client info should // correspond to |provider_host|. - const std::vector<mojom::ExtendableMessageEventPtr>& events = + const std::vector<blink::mojom::ExtendableMessageEventPtr>& events = static_cast<ExtendableMessageEventTestHelper*>(helper_.get())->events(); EXPECT_EQ(1u, events.size()); EXPECT_FALSE(events[0]->source_info_for_service_worker); @@ -415,7 +415,7 @@ EXPECT_TRUE(called); EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed, status); // No ExtendableMessageEvent has been dispatched. - const std::vector<mojom::ExtendableMessageEventPtr>& events = + const std::vector<blink::mojom::ExtendableMessageEventPtr>& events = static_cast<ExtendableMessageEventTestHelper*>(helper_.get())->events(); EXPECT_EQ(0u, events.size()); }
diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc index 02819c2..042f351 100644 --- a/content/browser/service_worker/service_worker_register_job.cc +++ b/content/browser/service_worker/service_worker_register_job.cc
@@ -20,7 +20,6 @@ #include "content/browser/service_worker/service_worker_version.h" #include "content/browser/service_worker/service_worker_write_to_cache_job.h" #include "content/browser/url_loader_factory_getter.h" -#include "content/common/service_worker/service_worker.mojom.h" #include "content/common/service_worker/service_worker_types.h" #include "content/common/service_worker/service_worker_utils.h" #include "content/public/browser/browser_thread.h"
diff --git a/content/browser/service_worker/service_worker_url_request_job.h b/content/browser/service_worker/service_worker_url_request_job.h index b947136..a116077 100644 --- a/content/browser/service_worker/service_worker_url_request_job.h +++ b/content/browser/service_worker/service_worker_url_request_job.h
@@ -23,7 +23,6 @@ #include "content/browser/service_worker/service_worker_response_type.h" #include "content/browser/service_worker/service_worker_url_job_wrapper.h" #include "content/common/content_export.h" -#include "content/common/service_worker/service_worker.mojom.h" #include "content/public/common/resource_type.h" #include "mojo/public/cpp/system/data_pipe.h" #include "net/http/http_byte_range.h"
diff --git a/content/browser/service_worker/service_worker_url_request_job_unittest.cc b/content/browser/service_worker/service_worker_url_request_job_unittest.cc index 2156f842..5d20b035 100644 --- a/content/browser/service_worker/service_worker_url_request_job_unittest.cc +++ b/content/browser/service_worker/service_worker_url_request_job_unittest.cc
@@ -501,7 +501,7 @@ const GURL& scope, const GURL& script_url, bool pause_after_download, - mojom::ServiceWorkerRequest service_worker_request, + blink::mojom::ServiceWorkerRequest service_worker_request, blink::mojom::ControllerServiceWorkerRequest controller_request, mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host, mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info, @@ -524,7 +524,7 @@ blink::mojom::FetchAPIRequestPtr /* request */, blink::mojom::FetchEventPreloadHandlePtr preload_handle, blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) + blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) override { embedded_worker_id_ = embedded_worker_id; response_callback_ = std::move(response_callback); @@ -537,7 +537,7 @@ GURL scope_; GURL script_url_; bool pause_after_download_; - mojom::ServiceWorkerRequest start_worker_request_; + blink::mojom::ServiceWorkerRequest start_worker_request_; blink::mojom::ControllerServiceWorkerRequest controller_request_; mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo start_worker_instance_host_; @@ -546,7 +546,7 @@ int embedded_worker_id_ = 0; blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback_; blink::mojom::FetchEventPreloadHandlePtr preload_handle_; - mojom::ServiceWorker::DispatchFetchEventCallback finish_callback_; + blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback_; ServiceWorkerURLRequestJobTest* test_; DISALLOW_COPY_AND_ASSIGN(DelayHelper); }; @@ -702,7 +702,7 @@ blink::mojom::FetchAPIRequestPtr /* request */, blink::mojom::FetchEventPreloadHandlePtr /* preload_handle */, blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) + blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) override { context()->RemoveProviderHost(mock_render_process_id(), kProviderID); response_callback->OnResponse( @@ -781,7 +781,7 @@ blink::mojom::FetchAPIRequestPtr /* request */, blink::mojom::FetchEventPreloadHandlePtr /* preload_handle */, blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) + blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) override { blink::mojom::FetchAPIResponsePtr response = MakeOkResponse(); response->headers = MakeHeaders(); @@ -882,7 +882,7 @@ blink::mojom::FetchAPIRequestPtr /* request */, blink::mojom::FetchEventPreloadHandlePtr /* preload_handle */, blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) + blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) override { ASSERT_FALSE(stream_handle_.is_null()); blink::mojom::FetchAPIResponsePtr response = MakeOkResponse(); @@ -1266,7 +1266,7 @@ blink::mojom::FetchEventPreloadHandlePtr /* preload_handle */, blink::mojom:: ServiceWorkerFetchResponseCallbackPtr /* response_callback */, - mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) + blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) override { SimulateWorkerStopped(embedded_worker_id); std::move(finish_callback) @@ -1357,7 +1357,7 @@ blink::mojom::FetchAPIRequestPtr /* request */, blink::mojom::FetchEventPreloadHandlePtr /* preload_handle */, blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback, - mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) + blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) override { finish_callback_ = std::move(finish_callback); response_callback->OnResponse( @@ -1365,7 +1365,7 @@ } private: - mojom::ServiceWorker::DispatchFetchEventCallback finish_callback_; + blink::mojom::ServiceWorker::DispatchFetchEventCallback finish_callback_; DISALLOW_COPY_AND_ASSIGN(EarlyResponseHelper); };
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc index 8d1d22a..7e6e194 100644 --- a/content/browser/service_worker/service_worker_version.cc +++ b/content/browser/service_worker/service_worker_version.cc
@@ -677,7 +677,8 @@ ServiceWorkerVersion::SimpleEventCallback ServiceWorkerVersion::CreateSimpleEventCallback(int request_id) { // The weak reference to |this| is safe because storage of the callbacks, the - // inflight responses of mojom::ServiceWorker messages, is owned by |this|. + // inflight responses of blink::mojom::ServiceWorker messages, is owned by + // |this|. return base::BindOnce(&ServiceWorkerVersion::OnSimpleEventFinished, base::Unretained(this), request_id); }
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h index 7a25c1ed..691f856e 100644 --- a/content/browser/service_worker/service_worker_version.h +++ b/content/browser/service_worker/service_worker_version.h
@@ -36,7 +36,6 @@ #include "content/browser/service_worker/service_worker_ping_controller.h" #include "content/browser/service_worker/service_worker_script_cache_map.h" #include "content/common/content_export.h" -#include "content/common/service_worker/service_worker.mojom.h" #include "content/common/service_worker/service_worker_types.h" #include "ipc/ipc_message.h" #include "mojo/public/cpp/bindings/interface_ptr.h" @@ -306,8 +305,9 @@ // the event, as well as the behavior for when the request times out. // // S13nServiceWorker: |timeout| and |timeout_behavior| don't have any effect. - // They are just ignored. Timeouts can be added to the mojom::ServiceWorker - // interface instead (see DispatchSyncEvent for an example). + // They are just ignored. Timeouts can be added to the + // blink::mojom::ServiceWorker interface instead (see DispatchSyncEvent for an + // example). int StartRequestWithCustomTimeout(ServiceWorkerMetrics::EventType event_type, StatusCallback error_callback, const base::TimeDelta& timeout, @@ -333,13 +333,13 @@ bool FinishExternalRequest(const std::string& request_uuid); // Creates a callback that is to be used for marking simple events dispatched - // through mojom::ServiceWorker as finished for the |request_id|. + // through blink::mojom::ServiceWorker as finished for the |request_id|. // Simple event means those events expecting a response with only a status // code and the dispatch time. See service_worker.mojom. SimpleEventCallback CreateSimpleEventCallback(int request_id); // This must be called when the worker is running. - mojom::ServiceWorker* endpoint() { + blink::mojom::ServiceWorker* endpoint() { DCHECK(running_status() == EmbeddedWorkerStatus::STARTING || running_status() == EmbeddedWorkerStatus::RUNNING); DCHECK(service_worker_ptr_.is_bound()); @@ -729,7 +729,7 @@ bool HasWorkInBrowser() const; // Callback function for simple events dispatched through mojo interface - // mojom::ServiceWorker. Use CreateSimpleEventCallback() to + // blink::mojom::ServiceWorker. Use CreateSimpleEventCallback() to // create a callback for a given |request_id|. void OnSimpleEventFinished(int request_id, blink::mojom::ServiceWorkerEventStatus status); @@ -839,7 +839,7 @@ std::set<std::string> pending_external_requests_; // Connected to ServiceWorkerContextClient while the worker is running. - mojom::ServiceWorkerPtr service_worker_ptr_; + blink::mojom::ServiceWorkerPtr service_worker_ptr_; // S13nServiceWorker: connected to the controller service worker. // |controller_request_| is non-null only when the |controller_ptr_| is
diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc index c828c32..848fc253 100644 --- a/content/browser/service_worker/service_worker_version_unittest.cc +++ b/content/browser/service_worker/service_worker_version_unittest.cc
@@ -246,7 +246,7 @@ const GURL& scope, const GURL& script_url, bool pause_after_download, - mojom::ServiceWorkerRequest service_worker_request, + blink::mojom::ServiceWorkerRequest service_worker_request, blink::mojom::ControllerServiceWorkerRequest controller_request, mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host, mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info, @@ -299,7 +299,7 @@ int /* embedded_worker_id */, mojom::EmbeddedWorkerInstanceHostAssociatedPtr /* instance_host_ptr */> instance_host_ptr_map_; - std::map<int /* embedded_worker_id */, mojom::ServiceWorkerRequest> + std::map<int /* embedded_worker_id */, blink::mojom::ServiceWorkerRequest> service_worker_request_map_; std::map<int /* embedded_worker_id */, blink::mojom::ControllerServiceWorkerRequest> @@ -907,9 +907,9 @@ ~MessageReceiverControlEvents() override {} void OnExtendableMessageEvent( - mojom::ExtendableMessageEventPtr event, - mojom::ServiceWorker::DispatchExtendableMessageEventCallback callback) - override { + blink::mojom::ExtendableMessageEventPtr event, + blink::mojom::ServiceWorker::DispatchExtendableMessageEventCallback + callback) override { EXPECT_FALSE(extendable_message_event_callback_); extendable_message_event_callback_ = std::move(callback); } @@ -925,7 +925,7 @@ return !extendable_message_event_callback_.is_null(); } - mojom::ServiceWorker::DispatchExtendableMessageEventCallback + blink::mojom::ServiceWorker::DispatchExtendableMessageEventCallback TakeExtendableMessageEventCallback() { return std::move(extendable_message_event_callback_); } @@ -935,7 +935,7 @@ } private: - mojom::ServiceWorker::DispatchExtendableMessageEventCallback + blink::mojom::ServiceWorker::DispatchExtendableMessageEventCallback extendable_message_event_callback_; base::OnceClosure stop_worker_callback_; }; @@ -953,7 +953,7 @@ ->has_extendable_message_event_callback(); } - mojom::ServiceWorker::DispatchExtendableMessageEventCallback + blink::mojom::ServiceWorker::DispatchExtendableMessageEventCallback TakeExtendableMessageEventCallback() { return static_cast<MessageReceiverControlEvents*>(helper_.get()) ->TakeExtendableMessageEventCallback(); @@ -982,7 +982,7 @@ // Dispatch a dummy event whose response will be received by SWVersion. EXPECT_FALSE(has_extendable_message_event_callback()); version_->endpoint()->DispatchExtendableMessageEvent( - mojom::ExtendableMessageEvent::New(), + blink::mojom::ExtendableMessageEvent::New(), version_->CreateSimpleEventCallback(request_id)); base::RunLoop().RunUntilIdle();
diff --git a/content/browser/webrtc/webrtc_capture_from_element_browsertest.cc b/content/browser/webrtc/webrtc_capture_from_element_browsertest.cc index d2f58a03..fec05c1 100644 --- a/content/browser/webrtc/webrtc_capture_from_element_browsertest.cc +++ b/content/browser/webrtc/webrtc_capture_from_element_browsertest.cc
@@ -109,9 +109,11 @@ MakeTypicalCall("testCanvasCapture(drawWebGL);", kCanvasCaptureTestHtmlFile); } -#if defined(OS_WIN) +#if defined(OS_WIN) || defined(OS_MACOSX) // https://crbug.com/869723 // Flaky on Windows 10 with Viz (i.e. in viz_content_browsertests). +// https://crbug.com/916928 +// Flaky on chromium.mac/Mac10.10 Tests #define MAYBE_VerifyCanvasCaptureOffscreenCanvasFrames \ DISABLED_VerifyCanvasCaptureOffscreenCanvasFrames #else
diff --git a/content/browser/webui/url_data_manager_backend.cc b/content/browser/webui/url_data_manager_backend.cc index 032f547..2839198 100644 --- a/content/browser/webui/url_data_manager_backend.cc +++ b/content/browser/webui/url_data_manager_backend.cc
@@ -126,13 +126,6 @@ // (This pattern is shared by most net::URLRequestJob implementations.) void StartAsync(); - // Due to a race condition, DevTools relies on a legacy thread hop to the UI - // thread before calling StartAsync. - // TODO(caseq): Fix the race condition and remove this thread hop in - // https://crbug.com/616641. - static void DelayStartForDevTools( - const base::WeakPtr<URLRequestChromeJob>& job); - // Post a task to copy |data_| to |buf_| on a worker thread, to avoid browser // jank. (|data_| might be mem-mapped, so a memcpy can trigger file ops). int PostReadTask(scoped_refptr<net::IOBuffer> buf, int buf_size); @@ -191,18 +184,6 @@ void URLRequestChromeJob::Start() { const GURL url = request_->url(); - // Due to a race condition, DevTools relies on a legacy thread hop to the UI - // thread before calling StartAsync. - // TODO(caseq): Fix the race condition and remove this thread hop in - // https://crbug.com/616641. - if (url.SchemeIs(kChromeDevToolsScheme)) { - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&URLRequestChromeJob::DelayStartForDevTools, - weak_factory_.GetWeakPtr())); - return; - } - // Start reading asynchronously so that all error reporting and data // callbacks happen as they would for network requests. base::ThreadTaskRunnerHandle::Get()->PostTask( @@ -343,13 +324,6 @@ return net::ERR_IO_PENDING; } -void URLRequestChromeJob::DelayStartForDevTools( - const base::WeakPtr<URLRequestChromeJob>& job) { - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&URLRequestChromeJob::StartAsync, job)); -} - void URLRequestChromeJob::StartAsync() { if (!request_) return;
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 3a4d9a04..1904759 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -177,6 +177,9 @@ WebRuntimeFeatures::EnableAutomationControlled(true); } + if (command_line.HasSwitch(switches::kEnableWebBluetoothScanning)) + WebRuntimeFeatures::EnableWebBluetoothScanning(true); + #if defined(OS_MACOSX) const bool enable_canvas_2d_image_chromium = command_line.HasSwitch(
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index a483eae..c5f1bc7 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -509,7 +509,6 @@ "renderer.mojom", "renderer_host.mojom", "service_worker/embedded_worker.mojom", - "service_worker/service_worker.mojom", "service_worker/service_worker_container.mojom", "service_worker/service_worker_provider.mojom", "shared_worker/shared_worker_factory.mojom", @@ -539,10 +538,6 @@ import_dirs = [ "//mojo/services" ] public_deps = [ - # Due to component_deps below, we're depending on blink_common, but - # blink_common does not export generated types of components/payments/mojom, - # so we need to specifically add this dependency here. - "//components/payments/mojom", "//components/services/leveldb/public/interfaces", "//content/public/common:interfaces", "//content/public/common:resource_type_bindings",
diff --git a/content/common/background_fetch/background_fetch_types.cc b/content/common/background_fetch/background_fetch_types.cc index 8357c7a..73eb2613 100644 --- a/content/common/background_fetch/background_fetch_types.cc +++ b/content/common/background_fetch/background_fetch_types.cc
@@ -8,7 +8,7 @@ blink::mojom::SerializedBlobPtr CloneSerializedBlob( const blink::mojom::SerializedBlobPtr& blob) { - if (!blob) + if (blob.is_null()) return nullptr; blink::mojom::BlobPtr blob_ptr(std::move(blob->blob)); blob_ptr->Clone(mojo::MakeRequest(&blob->blob)); @@ -25,7 +25,7 @@ const blink::mojom::FetchAPIResponsePtr& response) { // TODO(https://crbug.com/876546): Replace this method with response.Clone() // if the associated bug is fixed. - if (!response) + if (response.is_null()) return nullptr; return blink::mojom::FetchAPIResponse::New( response->url_list, response->status_code, response->status_text, @@ -39,7 +39,7 @@ // static blink::mojom::FetchAPIRequestPtr BackgroundFetchSettledFetch::CloneRequest( const blink::mojom::FetchAPIRequestPtr& request) { - if (!request) + if (request.is_null()) return nullptr; return blink::mojom::FetchAPIRequest::New( request->mode, request->is_main_resource_load, @@ -48,6 +48,7 @@ request->body, request->referrer.Clone(), request->credentials_mode, request->cache_mode, request->redirect_mode, request->integrity, request->priority, request->fetch_window_id, request->keepalive, - request->client_id, request->is_reload, request->is_history_navigation); + request->is_reload, request->is_history_navigation); } + } // namespace content
diff --git a/content/common/bluetooth/web_bluetooth_device_id.cc b/content/common/bluetooth/web_bluetooth_device_id.cc index 823ed0f..8dbae425 100644 --- a/content/common/bluetooth/web_bluetooth_device_id.cc +++ b/content/common/bluetooth/web_bluetooth_device_id.cc
@@ -16,17 +16,18 @@ } // namespace -WebBluetoothDeviceId::WebBluetoothDeviceId() {} +WebBluetoothDeviceId::WebBluetoothDeviceId() : is_mac_address_(false) {} -WebBluetoothDeviceId::WebBluetoothDeviceId(std::string device_id) - : device_id_(std::move(device_id)) { - CHECK(IsValid(device_id_)); +WebBluetoothDeviceId::WebBluetoothDeviceId(std::string device_id, + bool is_mac_address) + : device_id_(std::move(device_id)), is_mac_address_(is_mac_address) { + CHECK(IsValid()); } WebBluetoothDeviceId::~WebBluetoothDeviceId() {} const std::string& WebBluetoothDeviceId::str() const { - CHECK(IsValid(device_id_)); + CHECK(IsValid()); return device_id_; } @@ -42,11 +43,17 @@ base::Base64Encode(bytes, &bytes); - return WebBluetoothDeviceId(std::move(bytes)); + return WebBluetoothDeviceId(std::move(bytes), false); } // static -bool WebBluetoothDeviceId::IsValid(const std::string& device_id) { +bool WebBluetoothDeviceId::IsValid(const std::string& device_id, + bool is_mac_address) { + if (is_mac_address) { + // TODO(dougt) We should validate this as a MAC address. + return true; + } + std::string decoded; if (!base::Base64Decode(device_id, &decoded)) { return false; @@ -69,6 +76,10 @@ return true; } +bool WebBluetoothDeviceId::IsValid() const { + return WebBluetoothDeviceId::IsValid(device_id_, is_mac_address_); +} + bool WebBluetoothDeviceId::operator==( const WebBluetoothDeviceId& device_id) const { return str() == device_id.str();
diff --git a/content/common/bluetooth/web_bluetooth_device_id.h b/content/common/bluetooth/web_bluetooth_device_id.h index 2de12a0..cba30bc 100644 --- a/content/common/bluetooth/web_bluetooth_device_id.h +++ b/content/common/bluetooth/web_bluetooth_device_id.h
@@ -22,8 +22,9 @@ // resulting object will DCHECK-fail. WebBluetoothDeviceId(); - // DCHECKS that |device_id| is valid. - explicit WebBluetoothDeviceId(std::string device_id); + // CHECKS that |device_id| is valid if |is_mac_address| is false. + explicit WebBluetoothDeviceId(std::string device_id, + bool is_mac_address = false); ~WebBluetoothDeviceId(); // Returns the string that represents this WebBluetoothDeviceId. @@ -33,14 +34,21 @@ // string and base64-encoding it. static WebBluetoothDeviceId Create(); - // Returns true if base64-decoding |device_id| results in a 128bit string. - static bool IsValid(const std::string& device_id); + // If |is_mac_address| is true, the method will return true if |device_id| is + // a MAC address. If |is_mac_address| is false, this method will return true + // if |device_id| results in a 128bit base64-encoding string. Otherwise + // returns false. + static bool IsValid(const std::string& device_id, + bool is_mac_address = false); + + bool IsValid() const; bool operator==(const WebBluetoothDeviceId& device_id) const; bool operator!=(const WebBluetoothDeviceId& device_id) const; private: std::string device_id_; + bool is_mac_address_; }; // This is required by gtest to print a readable output on test failures.
diff --git a/content/common/service_worker/embedded_worker.mojom b/content/common/service_worker/embedded_worker.mojom index 30519f8..25ac1d2 100644 --- a/content/common/service_worker/embedded_worker.mojom +++ b/content/common/service_worker/embedded_worker.mojom
@@ -5,7 +5,6 @@ module content.mojom; import "content/common/native_types.mojom"; -import "content/common/service_worker/service_worker.mojom"; import "content/common/service_worker/service_worker_provider.mojom"; import "content/common/url_loader_factory_bundle.mojom"; import "content/public/common/renderer_preference_watcher.mojom"; @@ -16,6 +15,7 @@ import "services/service_manager/public/mojom/interface_provider.mojom"; import "third_party/blink/public/mojom/script/script_type.mojom"; import "third_party/blink/public/mojom/service_worker/controller_service_worker.mojom"; +import "third_party/blink/public/mojom/service_worker/service_worker.mojom"; import "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom"; import "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom"; import "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom"; @@ -62,7 +62,7 @@ RendererPreferences renderer_preferences; // Used to talk to the service worker from the browser process. - ServiceWorker& service_worker_request; + blink.mojom.ServiceWorker& service_worker_request; // S13nServiceWorker: cloned and passed to each controllee to directly // dispatch events from the controllees. blink.mojom.ControllerServiceWorker& controller_request;
diff --git a/content/common/service_worker/service_worker.mojom b/content/common/service_worker/service_worker.mojom deleted file mode 100644 index 68bd24d..0000000 --- a/content/common/service_worker/service_worker.mojom +++ /dev/null
@@ -1,171 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -module content.mojom; - -import "mojo/public/mojom/base/string16.mojom"; -import "mojo/public/mojom/base/time.mojom"; -import "services/network/public/mojom/cookie_manager.mojom"; -import "third_party/blink/public/mojom/background_fetch/background_fetch.mojom"; -import "third_party/blink/public/mojom/fetch/fetch_api_response.mojom"; -import "third_party/blink/public/mojom/messaging/transferable_message.mojom"; -import "third_party/blink/public/mojom/notifications/notification.mojom"; -import "third_party/blink/public/mojom/payments/payment_app.mojom"; -import "third_party/blink/public/mojom/service_worker/dispatch_fetch_event_params.mojom"; -import "third_party/blink/public/mojom/service_worker/service_worker.mojom"; -import "third_party/blink/public/mojom/service_worker/service_worker_client.mojom"; -import "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom"; -import "third_party/blink/public/mojom/service_worker/service_worker_fetch_response_callback.mojom"; -import "third_party/blink/public/mojom/service_worker/service_worker_object.mojom"; -import "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom"; -import "url/mojom/origin.mojom"; -import "url/mojom/url.mojom"; - -struct ExtendableMessageEvent { - blink.mojom.TransferableMessage message; - url.mojom.Origin source_origin; - // Exactly one of |source_info_for_client| and - // |source_info_for_service_worker| should be non-null. - blink.mojom.ServiceWorkerClientInfo? source_info_for_client; - blink.mojom.ServiceWorkerObjectInfo? source_info_for_service_worker; -}; - -// The number of seconds for which a 'push' event should be allowed to run. -// This is not in the spec but for a Chrome-specific timeout. Each -// event dispatched to service workers has a 5 minute timeout in the Chrome -// implementation, but this makes the timeout for push events shorter. -const int32 kPushEventTimeoutSeconds = 90; - -// An interface for talking to a running service worker thread. The browser -// process uses this interface to request the renderer to do things like -// dispatch events to the service worker. This interface is bound on the -// service worker thread and is implemented by ServiceWorkerContextClient. -// -// This is the master interface for the Mojo message pipe between the browser -// process and the service worker thread in the renderer process. Other service -// worker-related interfaces bound on the service worker thread are associated -// with this interface. These include: -// - ServiceWorkerHost for this service worker. -// - ServiceWorkerRegistrationObject(Host) for this service worker's -// self.registration property. -// - ServiceWorkerObjects(Host) for that registration's properties. -// -// A similar (but non-associated) interface is ControllerServiceWorker. That -// interface is used by service worker clients (inside renderer processes) to -// talk directly to their controller service worker, without going through the -// browser. -// -// USAGE TIP: Those DispatchEvent* messages expecting a -// (blink.mojom.ServiceWorkerEventStatus, mojo_base.mojom.TimeTicks) callback -// are considered 'simple events'. -// ServiceWorkerVersion::CreateSimpleEventCallback can be used to create the -// callback for these. -interface ServiceWorker { - // The first message sent on this interface. It is used to associate service - // worker-related interfaces together on the service worker thread, as - // ServiceWorker is the first interface available on the - // service worker thread. It establishes the |service_worker_host| connection - // and passes information used to populate - // ServiceWorkerGlobalScope#registration object. JavaScript execution of the - // service worker does not start until this message is received. - InitializeGlobalScope( - associated blink.mojom.ServiceWorkerHost service_worker_host, - blink.mojom.ServiceWorkerRegistrationObjectInfo registration_info); - - DispatchInstallEvent() - => (blink.mojom.ServiceWorkerEventStatus status, - bool has_fetch_handler); - DispatchActivateEvent() - => (blink.mojom.ServiceWorkerEventStatus status); - - // These methods dispatch to the ServiceWorkerGlobalScope the events listed on - // https://wicg.github.io/background-fetch/#service-worker-global-events. - // The callbacks are called once the event handler has run and waitUntil() - // promise has settled. |developer_id| and |unique_id| are documented in - // content::BackgroundFetchRegistrationId. - DispatchBackgroundFetchAbortEvent( - blink.mojom.BackgroundFetchRegistration registration) - => (blink.mojom.ServiceWorkerEventStatus status); - DispatchBackgroundFetchClickEvent( - blink.mojom.BackgroundFetchRegistration registration) - => (blink.mojom.ServiceWorkerEventStatus status); - DispatchBackgroundFetchFailEvent( - blink.mojom.BackgroundFetchRegistration registration) - => (blink.mojom.ServiceWorkerEventStatus status); - DispatchBackgroundFetchSuccessEvent( - blink.mojom.BackgroundFetchRegistration registration) - => (blink.mojom.ServiceWorkerEventStatus status); - - // Dispatches the cookie change events in the Async Cookie API specification. - // https://github.com/WICG/cookie-store/ - // The callback is called once the event handler has run and the waitUntil() - // promise has settled. - DispatchCookieChangeEvent( - network.mojom.CanonicalCookie cookie, - network.mojom.CookieChangeCause cause) - => (blink.mojom.ServiceWorkerEventStatus status); - - // The Dispatch*FetchEvent() callback is called once the event finishes, - // which means the event handler ran and all outstanding respondWith() and - // waitUntil() promises have settled. |response_callback| is called once the - // promise to respondWith() settles, or when the event handler ran without - // calling respondWith(). - DispatchFetchEvent( - blink.mojom.DispatchFetchEventParams params, - blink.mojom.ServiceWorkerFetchResponseCallback response_callback) - => (blink.mojom.ServiceWorkerEventStatus status); - - DispatchNotificationClickEvent( - string notification_id, - blink.mojom.NotificationData notification_data, - int32 action_index, - mojo_base.mojom.String16? reply) - => (blink.mojom.ServiceWorkerEventStatus status); - DispatchNotificationCloseEvent( - string notification_id, - blink.mojom.NotificationData notification_data) - => (blink.mojom.ServiceWorkerEventStatus status); - // The payload of a push message can be valid with content, valid with empty - // content, or null. - DispatchPushEvent(string? payload) - => (blink.mojom.ServiceWorkerEventStatus status); - // Arguments are passed to the event handler as parameters of SyncEvent. - // Ref: https://wicg.github.io/BackgroundSync/spec/#sync-event - // S13nServiceWorker: |timeout| is the amount of time to allow this event to - // finish. - // Non-S13nServiceWorker: |timeout| is just ignored. - DispatchSyncEvent(string id, - bool last_chance, - mojo_base.mojom.TimeDelta timeout) - => (blink.mojom.ServiceWorkerEventStatus status); - DispatchAbortPaymentEvent( - payments.mojom.PaymentHandlerResponseCallback result_of_abort_payment) - => (blink.mojom.ServiceWorkerEventStatus status); - DispatchCanMakePaymentEvent( - payments.mojom.CanMakePaymentEventData event_data, - payments.mojom.PaymentHandlerResponseCallback result_of_can_make_payment) - => (blink.mojom.ServiceWorkerEventStatus status); - DispatchPaymentRequestEvent( - payments.mojom.PaymentRequestEventData request_data, - payments.mojom.PaymentHandlerResponseCallback response_callback) - => (blink.mojom.ServiceWorkerEventStatus status); - DispatchExtendableMessageEvent(ExtendableMessageEvent event) - => (blink.mojom.ServiceWorkerEventStatus status); - - // TODO(crbug.com/869714): Remove this code for long living service workers - // when Android Messages no longer requires it. - DispatchExtendableMessageEventWithCustomTimeout(ExtendableMessageEvent event, - mojo_base.mojom.TimeDelta timeout) - => (blink.mojom.ServiceWorkerEventStatus status); - - // Pings the service worker to check if it is responsive. If the callback is - // not called within a certain period of time, the browser will terminate the - // worker. - Ping() => (); - - // S13nServiceWorker: - // Lets the idle timer request termination immediately after all inflight - // events are handled without delay. - SetIdleTimerDelayToZero(); -};
diff --git a/content/common/service_worker/service_worker_types.proto b/content/common/service_worker/service_worker_types.proto index 1bb4de0..d8d1731e 100644 --- a/content/common/service_worker/service_worker_types.proto +++ b/content/common/service_worker/service_worker_types.proto
@@ -10,7 +10,7 @@ // Serializable version of ServiceWorkerFetchRequest. // -// Next Tag: 15 +// Next Tag: 17 message ServiceWorkerFetchRequest { // Serializable version of the Referrer struct defined in // https://cs.chromium.org/chromium/src/content/public/common/referrer.h @@ -37,7 +37,7 @@ optional int32 redirect_mode = 11; // network::mojom::FetchRedirectMode. optional string integrity = 12; optional bool keepalive = 13; - optional string client_id = 14; + reserved 14; // Obsolete: this used to be client_id. It was removed. reserved 15; // for is_reload_navigation optional bool is_history_navigation = 16; -} \ No newline at end of file +}
diff --git a/content/common/service_worker/service_worker_types_unittest.cc b/content/common/service_worker/service_worker_types_unittest.cc index cd77e299..4873724 100644 --- a/content/common/service_worker/service_worker_types_unittest.cc +++ b/content/common/service_worker/service_worker_types_unittest.cc
@@ -30,7 +30,6 @@ request->redirect_mode = network::mojom::FetchRedirectMode::kManual; request->integrity = "integrity"; request->keepalive = true; - request->client_id = "42"; request->is_reload = true; EXPECT_EQ(
diff --git a/content/common/service_worker/service_worker_utils.cc b/content/common/service_worker/service_worker_utils.cc index 2888ed2..c3dcafaa8 100644 --- a/content/common/service_worker/service_worker_utils.cc +++ b/content/common/service_worker/service_worker_utils.cc
@@ -237,8 +237,6 @@ request_proto.set_integrity(request.integrity.value()); request_proto.set_keepalive(request.keepalive); request_proto.set_is_history_navigation(request.is_history_navigation); - if (request.client_id) - request_proto.set_client_id(request.client_id.value()); return request_proto.SerializeAsString(); } @@ -279,8 +277,6 @@ request_ptr->integrity = request_proto.integrity(); request_ptr->keepalive = request_proto.keepalive(); request_ptr->is_history_navigation = request_proto.is_history_navigation(); - if (request_proto.has_client_id()) - request_ptr->client_id = request_proto.client_id(); return request_ptr; }
diff --git a/content/public/browser/media_session.h b/content/public/browser/media_session.h index ef8cf165..b08533a5e 100644 --- a/content/public/browser/media_session.h +++ b/content/public/browser/media_session.h
@@ -29,13 +29,6 @@ ~MediaSession() override = default; - // Return if the session can be controlled by Resume() and Suspend() calls - // above. - virtual bool IsControllable() const = 0; - - // Return if the actual playback state is paused. - virtual bool IsActuallyPaused() const = 0; - // Tell the media session a user action has performed. virtual void DidReceiveAction( media_session::mojom::MediaSessionAction action) = 0;
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 852baf21..87391bb 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -96,6 +96,11 @@ // features. const char kDisableBlinkFeatures[] = "disable-blink-features"; +// Enable Web Bluetooth Scanning +// This switch enables Web Bluetooth Scanning without any +// permission prompt for testing. +const char kEnableWebBluetoothScanning[] = "enable-web-bluetooth-scanning"; + // Disables compositor Ukm recording in browser tests. // TODO(khushalsagar): Remove once crbug.com/761524 is resolved. const char kDisableCompositorUkmForTests[] = "disable-compositor-ukm-for-tests";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index f7b57bdd..7d728317 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -140,6 +140,7 @@ CONTENT_EXPORT extern const char kEnableVtune[]; CONTENT_EXPORT extern const char kEnableVulkan[]; CONTENT_EXPORT extern const char kEnableWebAuthTestingAPI[]; +CONTENT_EXPORT extern const char kEnableWebBluetoothScanning[]; CONTENT_EXPORT extern const char kEnableWebGL2ComputeContext[]; CONTENT_EXPORT extern const char kEnableWebGLDraftExtensions[]; CONTENT_EXPORT extern const char kEnableWebGLImageChromium[];
diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h index 86e8152..ab52332 100644 --- a/content/public/renderer/content_renderer_client.h +++ b/content/public/renderer/content_renderer_client.h
@@ -138,21 +138,24 @@ // (lack of information on the error code) so the caller should take care to // initialize it with a safe default before the call. virtual void PrepareErrorPage(content::RenderFrame* render_frame, - const blink::WebURLRequest& failed_request, const blink::WebURLError& error, + const std::string& http_method, + bool ignoring_cache, std::string* error_html) {} + virtual void PrepareErrorPageForHttpStatusError( content::RenderFrame* render_frame, - const blink::WebURLRequest& failed_request, const GURL& unreachable_url, + const std::string& http_method, + bool ignoring_cache, int http_status, std::string* error_html) {} // Returns as |error_description| a brief description of the error that // ocurred. The out parameter may be not written to in certain cases (lack of // information on the error code) - virtual void GetErrorDescription(const blink::WebURLRequest& failed_request, - const blink::WebURLError& error, + virtual void GetErrorDescription(const blink::WebURLError& error, + const std::string& http_method, base::string16* error_description) {} // Allows the embedder to control when media resources are loaded. Embedders
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc index 3588950..9e74214 100644 --- a/content/public/test/render_view_test.cc +++ b/content/public/test/render_view_test.cc
@@ -434,9 +434,9 @@ } void RenderViewTest::SendInputEvent(const blink::WebInputEvent& input_event) { - RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); - impl->HandleInputEvent(blink::WebCoalescedInputEvent(input_event), - ui::LatencyInfo(), HandledEventCallback()); + RenderWidget* widget = static_cast<RenderViewImpl*>(view_)->GetWidget(); + widget->HandleInputEvent(blink::WebCoalescedInputEvent(input_event), + ui::LatencyInfo(), HandledEventCallback()); } void RenderViewTest::SendWebKeyboardEvent( @@ -515,12 +515,12 @@ mouse_event.button = WebMouseEvent::Button::kLeft; mouse_event.SetPositionInWidget(point.x(), point.y()); mouse_event.click_count = 1; - RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); - impl->HandleInputEvent(blink::WebCoalescedInputEvent(mouse_event), - ui::LatencyInfo(), HandledEventCallback()); + RenderWidget* widget = static_cast<RenderViewImpl*>(view_)->GetWidget(); + widget->HandleInputEvent(blink::WebCoalescedInputEvent(mouse_event), + ui::LatencyInfo(), HandledEventCallback()); mouse_event.SetType(WebInputEvent::kMouseUp); - impl->HandleInputEvent(blink::WebCoalescedInputEvent(mouse_event), - ui::LatencyInfo(), HandledEventCallback()); + widget->HandleInputEvent(blink::WebCoalescedInputEvent(mouse_event), + ui::LatencyInfo(), HandledEventCallback()); } @@ -538,12 +538,12 @@ mouse_event.button = WebMouseEvent::Button::kRight; mouse_event.SetPositionInWidget(point.x(), point.y()); mouse_event.click_count = 1; - RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); - impl->HandleInputEvent(blink::WebCoalescedInputEvent(mouse_event), - ui::LatencyInfo(), HandledEventCallback()); + RenderWidget* widget = static_cast<RenderViewImpl*>(view_)->GetWidget(); + widget->HandleInputEvent(blink::WebCoalescedInputEvent(mouse_event), + ui::LatencyInfo(), HandledEventCallback()); mouse_event.SetType(WebInputEvent::kMouseUp); - impl->HandleInputEvent(blink::WebCoalescedInputEvent(mouse_event), - ui::LatencyInfo(), HandledEventCallback()); + widget->HandleInputEvent(blink::WebCoalescedInputEvent(mouse_event), + ui::LatencyInfo(), HandledEventCallback()); } void RenderViewTest::SimulateRectTap(const gfx::Rect& rect) { @@ -554,10 +554,10 @@ gesture_event.data.tap.tap_count = 1; gesture_event.data.tap.width = rect.width(); gesture_event.data.tap.height = rect.height(); - RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); - impl->HandleInputEvent(blink::WebCoalescedInputEvent(gesture_event), - ui::LatencyInfo(), HandledEventCallback()); - impl->FocusChangeComplete(); + RenderWidget* widget = static_cast<RenderViewImpl*>(view_)->GetWidget(); + widget->HandleInputEvent(blink::WebCoalescedInputEvent(gesture_event), + ui::LatencyInfo(), HandledEventCallback()); + widget->FocusChangeComplete(); } void RenderViewTest::SetFocused(const blink::WebNode& node) {
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 59286b1..fc0ab4e 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -496,9 +496,9 @@ "render_view_win.cc", "render_widget.cc", "render_widget.h", + "render_widget_delegate.h", "render_widget_mouse_lock_dispatcher.cc", "render_widget_mouse_lock_dispatcher.h", - "render_widget_owner_delegate.h", "renderer_blink_platform_impl.cc", "renderer_blink_platform_impl.h", "renderer_main.cc",
diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc index bf8adda..af99d72 100644 --- a/content/renderer/browser_plugin/browser_plugin.cc +++ b/content/renderer/browser_plugin/browser_plugin.cc
@@ -229,7 +229,7 @@ } RendererWindowTreeClient* renderer_window_tree_client = RendererWindowTreeClient::Get( - render_frame->GetRenderWidget()->routing_id()); + render_frame->GetLocalRootRenderWidget()->routing_id()); DCHECK(renderer_window_tree_client); mus_embedded_frame_ = renderer_window_tree_client->CreateMusEmbeddedFrame(this, embed_token); @@ -523,7 +523,7 @@ embedding_render_widget_ = RenderFrameImpl::FromWebFrame(container_->GetDocument().GetFrame()) - ->GetRenderWidget() + ->GetLocalRootRenderWidget() ->AsWeakPtr(); embedding_render_widget_->RegisterBrowserPlugin(this);
diff --git a/content/renderer/browser_render_view_browsertest.cc b/content/renderer/browser_render_view_browsertest.cc index 2fe5e36..73c65dd 100644 --- a/content/renderer/browser_render_view_browsertest.cc +++ b/content/renderer/browser_render_view_browsertest.cc
@@ -55,8 +55,9 @@ latest_error_stale_copy_in_cache_(false) {} void PrepareErrorPage(content::RenderFrame* render_frame, - const blink::WebURLRequest& failed_request, const blink::WebURLError& error, + const std::string& http_method, + bool ignoring_cache, std::string* error_html) override { if (error_html) *error_html = "A suffusion of yellow.";
diff --git a/content/renderer/external_popup_menu_browsertest.cc b/content/renderer/external_popup_menu_browsertest.cc index d3cff681..0ea34d8 100644 --- a/content/renderer/external_popup_menu_browsertest.cc +++ b/content/renderer/external_popup_menu_browsertest.cc
@@ -12,6 +12,7 @@ #include "content/renderer/render_view_impl.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/web_size.h" +#include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_view.h" // Tests for the external select popup menu (Mac specific). @@ -153,6 +154,31 @@ EXPECT_FALSE(SimulateElementClick(kSelectID)); } +// crbug.com/912211 +TEST_F(ExternalPopupMenuRemoveTest, RemoveFrameOnChange) { + LoadHTML( + "<style>* { margin: 0; } iframe { border: 0; }</style>" + "<body><iframe srcdoc=\"" + "<style>* { margin: 0; }</style><select><option>opt1<option>opt2" + "\"></iframe>" + "<script>" + "onload = function() {" + " const frame = document.querySelector('iframe');" + " frame.contentDocument.querySelector('select').onchange = " + " () => { frame.remove(); };" + "};" + "</script>"); + // Open a popup. + SimulatePointClick(gfx::Point(8, 8)); + // Select something on the sub-frame, it causes the frame to be removed from + // the page. + auto* child_web_frame = + static_cast<blink::WebLocalFrame*>(frame()->GetWebFrame()->FirstChild()); + static_cast<RenderFrameImpl*>(RenderFrame::FromWebFrame(child_web_frame)) + ->OnSelectPopupMenuItem(1); + // The test passes if the test didn't crash and ASAN didn't complain. +} + class ExternalPopupMenuDisplayNoneTest : public ExternalPopupMenuTest { public: ExternalPopupMenuDisplayNoneTest() {}
diff --git a/content/renderer/input/frame_input_handler_impl.cc b/content/renderer/input/frame_input_handler_impl.cc index 606a1fa..ec3f18c 100644 --- a/content/renderer/input/frame_input_handler_impl.cc +++ b/content/renderer/input/frame_input_handler_impl.cc
@@ -26,10 +26,10 @@ mojom::FrameInputHandlerRequest request) : binding_(this), render_frame_(render_frame), - input_event_queue_(render_frame->GetRenderWidget()->GetInputEventQueue()), + input_event_queue_( + render_frame->GetLocalRootRenderWidget()->GetInputEventQueue()), main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), - weak_ptr_factory_(this) -{ + weak_ptr_factory_(this) { weak_this_ = weak_ptr_factory_.GetWeakPtr(); // If we have created an input event queue move the mojo request over to the // compositor thread. @@ -80,7 +80,7 @@ if (!render_frame_) return; - ImeEventGuard guard(render_frame_->GetRenderWidget()); + ImeEventGuard guard(render_frame_->GetLocalRootRenderWidget()); render_frame_->GetWebFrame()->SetCompositionFromExistingText( start, end, ConvertUiImeTextSpansToBlinkImeTextSpans(ui_ime_text_spans)); @@ -309,7 +309,7 @@ if (render_frame_) { blink::WebLocalFrame* frame = render_frame_->GetWebFrame(); blink::WebRange initial_range = frame->SelectionRange(); - render_frame_->GetRenderWidget()->SetHandlingInputEvent(true); + render_frame_->GetLocalRootRenderWidget()->SetHandlingInputEvent(true); if (!initial_range.IsNull()) did_select = frame->SelectWordAroundCaret(); if (did_select) { @@ -318,7 +318,7 @@ start_adjust = adjusted_range.StartOffset() - initial_range.StartOffset(); end_adjust = adjusted_range.EndOffset() - initial_range.EndOffset(); } - render_frame_->GetRenderWidget()->SetHandlingInputEvent(false); + render_frame_->GetLocalRootRenderWidget()->SetHandlingInputEvent(false); } // If the mojom channel is registered with compositor thread, we have to run @@ -429,7 +429,7 @@ } if (!render_frame_) return; - render_frame_->GetRenderWidget() + render_frame_->GetLocalRootRenderWidget() ->widget_input_handler_manager() ->AddAssociatedInterface(std::move(interface_request), std::move(host)); }
diff --git a/content/renderer/input/input_target_client_impl.cc b/content/renderer/input/input_target_client_impl.cc index 4fd92d4d..3704cc4e 100644 --- a/content/renderer/input/input_target_client_impl.cc +++ b/content/renderer/input/input_target_client_impl.cc
@@ -32,8 +32,9 @@ "step", "FrameSinkIdAt"); gfx::PointF local_point; - viz::FrameSinkId id = render_frame_->GetRenderWidget()->GetFrameSinkIdAtPoint( - point, &local_point); + viz::FrameSinkId id = + render_frame_->GetLocalRootRenderWidget()->GetFrameSinkIdAtPoint( + point, &local_point); std::move(callback).Run(id, local_point); }
diff --git a/content/renderer/mus/renderer_window_tree_client.cc b/content/renderer/mus/renderer_window_tree_client.cc index 42515d8..9ee9cbdf 100644 --- a/content/renderer/mus/renderer_window_tree_client.cc +++ b/content/renderer/mus/renderer_window_tree_client.cc
@@ -379,8 +379,8 @@ void RendererWindowTreeClient::GetScreenProviderObserver( ws::mojom::ScreenProviderObserverAssociatedRequest observer) {} -void RendererWindowTreeClient::OnOcclusionStateChanged( - ws::Id window_id, - ws::mojom::OcclusionState occlusion_state) {} +void RendererWindowTreeClient::OnOcclusionStatesChanged( + const base::flat_map<ws::Id, ws::mojom::OcclusionState>& + occlusion_changes) {} } // namespace content
diff --git a/content/renderer/mus/renderer_window_tree_client.h b/content/renderer/mus/renderer_window_tree_client.h index d6758e1a..46e9b2d 100644 --- a/content/renderer/mus/renderer_window_tree_client.h +++ b/content/renderer/mus/renderer_window_tree_client.h
@@ -201,9 +201,9 @@ void RequestClose(ws::Id window_id) override; void GetScreenProviderObserver( ws::mojom::ScreenProviderObserverAssociatedRequest observer) override; - void OnOcclusionStateChanged( - ws::Id window_id, - ws::mojom::OcclusionState occlusion_state) override; + void OnOcclusionStatesChanged( + const base::flat_map<ws::Id, ws::mojom::OcclusionState>& + occlusion_changes) override; const int routing_id_; ws::Id root_window_id_ = 0u;
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc index df29eef..85176ba 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.cc +++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -558,10 +558,11 @@ if (render_frame_) { // NULL in tests or if the frame has been destroyed. render_frame_->PepperInstanceCreated(this); - view_data_.is_page_visible = !render_frame_->GetRenderWidget()->is_hidden(); + view_data_.is_page_visible = + !render_frame_->GetLocalRootRenderWidget()->is_hidden(); // Set the initial focus. - SetContentAreaFocus(render_frame_->GetRenderWidget()->has_focus()); + SetContentAreaFocus(render_frame_->GetLocalRootRenderWidget()->has_focus()); if (!module_->IsProxied()) { PepperBrowserConnection* browser_connection = @@ -1145,7 +1146,8 @@ (event.GetModifiers() & blink::WebInputEvent::kLeftButtonDown)) { has_been_clicked_ = true; blink::WebRect bounds = container()->GetElement().BoundsInViewport(); - render_frame()->GetRenderWidget()->ConvertViewportToWindow(&bounds); + render_frame()->GetLocalRootRenderWidget()->ConvertViewportToWindow( + &bounds); RecordFlashClickSizeMetric(bounds.width, bounds.height); } @@ -1300,7 +1302,7 @@ view_data_.css_scale = container_->PageZoomFactor() * container_->PageScaleFactor(); blink::WebFloatRect windowToViewportScale(0, 0, 1.0f, 0); - render_frame()->GetRenderWidget()->ConvertWindowToViewport( + render_frame()->GetLocalRootRenderWidget()->ConvertWindowToViewport( &windowToViewportScale); viewport_to_dip_scale_ = 1.0f / windowToViewportScale.width; ConvertRectToDIP(&view_data_.rect); @@ -1323,7 +1325,7 @@ if (desired_fullscreen_state_ || view_data_.is_fullscreen) { bool is_fullscreen_element = container_->IsFullscreenElement(); if (!view_data_.is_fullscreen && desired_fullscreen_state_ && - render_frame()->GetRenderWidget()->is_fullscreen_granted() && + render_frame()->GetLocalRootRenderWidget()->is_fullscreen_granted() && is_fullscreen_element) { // Entered fullscreen. Only possible via SetFullscreen(). view_data_.is_fullscreen = true; @@ -2708,7 +2710,7 @@ *size = view_data_.rect.size; } else { // All other cases: Report the screen size. - if (!render_frame_ || !render_frame_->GetRenderWidget()) + if (!render_frame_ || !render_frame_->GetLocalRootRenderWidget()) return PP_FALSE; blink::WebScreenInfo info = render_frame_->render_view()->GetScreenInfo(); *size = PP_MakeSize(info.rect.width, info.rect.height); @@ -2978,8 +2980,7 @@ WebLocalFrame* frame = document.GetFrame(); if (!frame) return PP_MakeUndefined(); - const WebURLRequest& request = frame->GetDocumentLoader()->OriginalRequest(); - WebString referer = request.HttpHeaderField("Referer"); + WebString referer = frame->GetDocumentLoader()->OriginalReferrer(); if (referer.IsEmpty()) return PP_MakeUndefined(); return ppapi::PPB_URLUtil_Shared::GenerateURLReturn( @@ -3375,7 +3376,7 @@ return container->mouse_lock_dispatcher(); } if (render_frame_) - return render_frame_->GetRenderWidget()->mouse_lock_dispatcher(); + return render_frame_->GetLocalRootRenderWidget()->mouse_lock_dispatcher(); return nullptr; }
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index a69e8c11..2ebaec5 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -416,7 +416,7 @@ if (!redirects.empty()) return redirects.at(0); - return document_loader->OriginalRequest().Url(); + return document_loader->OriginalUrl(); } // Returns false unless this is a top-level navigation. @@ -1756,7 +1756,7 @@ void RenderFrameImpl::Initialize() { is_main_frame_ = !frame_->Parent(); - GetRenderWidget()->RegisterRenderFrame(this); + GetLocalRootRenderWidget()->RegisterRenderFrame(this); RenderFrameImpl* parent_frame = RenderFrameImpl::FromWebFrame(frame_->Parent()); @@ -1831,10 +1831,14 @@ } } -RenderWidget* RenderFrameImpl::GetRenderWidget() { +RenderWidget* RenderFrameImpl::GetLocalRootRenderWidget() { return GetLocalRoot()->render_widget_.get(); } +RenderWidget* RenderFrameImpl::GetMainFrameRenderWidget() { + return render_view()->GetWidget(); +} + #if BUILDFLAG(ENABLE_PLUGINS) void RenderFrameImpl::PepperPluginCreated(RendererPpapiHost* host) { for (auto& observer : observers_) @@ -1850,7 +1854,7 @@ // the plugin would like to set an invisible cursor when there isn't any user // input for a while. if (instance == pepper_last_mouse_event_target_) - GetRenderWidget()->DidChangeCursor(cursor); + GetLocalRootRenderWidget()->DidChangeCursor(cursor); } void RenderFrameImpl::PepperDidReceiveMouseEvent( @@ -1863,7 +1867,7 @@ if (instance != focused_pepper_plugin_) return; - GetRenderWidget()->UpdateTextInputState(); + GetLocalRootRenderWidget()->UpdateTextInputState(); FocusedNodeChangedForAccessibility(WebNode()); } @@ -1872,20 +1876,20 @@ PepperPluginInstanceImpl* instance) { if (instance != focused_pepper_plugin_) return; - GetRenderWidget()->UpdateSelectionBounds(); + GetLocalRootRenderWidget()->UpdateSelectionBounds(); } void RenderFrameImpl::PepperCancelComposition( PepperPluginInstanceImpl* instance) { if (instance != focused_pepper_plugin_) return; - if (mojom::WidgetInputHandlerHost* host = GetRenderWidget() + if (mojom::WidgetInputHandlerHost* host = GetLocalRootRenderWidget() ->widget_input_handler_manager() ->GetWidgetInputHandlerHost()) { host->ImeCancelComposition(); } #if defined(OS_MACOSX) || defined(USE_AURA) - GetRenderWidget()->UpdateCompositionInfo( + GetLocalRootRenderWidget()->UpdateCompositionInfo( false /* not an immediate request */); #endif } @@ -1925,8 +1929,9 @@ // web ScreenInfo or the original ScreenInfo here. RenderWidgetFullscreenPepper* widget = RenderWidgetFullscreenPepper::Create( fullscreen_widget_routing_id, std::move(show_callback), - GetRenderWidget()->compositor_deps(), plugin, std::move(main_frame_url), - GetRenderWidget()->GetWebScreenInfo(), std::move(widget_channel_request)); + GetLocalRootRenderWidget()->compositor_deps(), plugin, + std::move(main_frame_url), GetLocalRootRenderWidget()->GetWebScreenInfo(), + std::move(widget_channel_request)); // TODO(nick): The show() handshake seems like unnecessary complexity here, // since there's no real delay between CreateFullscreenWidget and // ShowCreatedFullscreenWidget. Would it be simpler to have the @@ -1954,20 +1959,21 @@ const std::vector<blink::WebImeTextSpan>& ime_text_spans, int selection_start, int selection_end) { - render_view_->OnImeSetComposition(text, ime_text_spans, - gfx::Range::InvalidRange(), selection_start, - selection_end); + GetMainFrameRenderWidget()->OnImeSetComposition( + text, ime_text_spans, gfx::Range::InvalidRange(), selection_start, + selection_end); } void RenderFrameImpl::SimulateImeCommitText( const base::string16& text, const std::vector<blink::WebImeTextSpan>& ime_text_spans, const gfx::Range& replacement_range) { - render_view_->OnImeCommitText(text, ime_text_spans, replacement_range, 0); + GetMainFrameRenderWidget()->OnImeCommitText(text, ime_text_spans, + replacement_range, 0); } void RenderFrameImpl::SimulateImeFinishComposingText(bool keep_selection) { - render_view_->OnImeFinishComposingText(keep_selection); + GetMainFrameRenderWidget()->OnImeFinishComposingText(keep_selection); } void RenderFrameImpl::OnImeSetComposition( @@ -2370,13 +2376,13 @@ void RenderFrameImpl::OnCopyImageAt(int x, int y) { blink::WebFloatRect viewport_position(x, y, 0, 0); - GetRenderWidget()->ConvertWindowToViewport(&viewport_position); + GetLocalRootRenderWidget()->ConvertWindowToViewport(&viewport_position); frame_->CopyImageAt(WebPoint(viewport_position.x, viewport_position.y)); } void RenderFrameImpl::OnSaveImageAt(int x, int y) { blink::WebFloatRect viewport_position(x, y, 0, 0); - GetRenderWidget()->ConvertWindowToViewport(&viewport_position); + GetLocalRootRenderWidget()->ConvertWindowToViewport(&viewport_position); frame_->SaveImageAt(WebPoint(viewport_position.x, viewport_position.y)); } @@ -2518,7 +2524,7 @@ } void RenderFrameImpl::OnVisualStateRequest(uint64_t id) { - GetRenderWidget()->QueueMessage( + GetLocalRootRenderWidget()->QueueMessage( new FrameHostMsg_VisualStateResponse(routing_id_, id)); } @@ -2768,7 +2774,8 @@ return; // Notify the browser that we failed a provisional load with an error. - SendFailedProvisionalLoad(document_loader->GetRequest(), error, frame_); + SendFailedProvisionalLoad(document_loader->GetRequest().HttpMethod().Ascii(), + error, frame_); if (!ShouldDisplayErrorPageForFailedLoad(error.reason(), error.url())) return; @@ -2808,8 +2815,11 @@ if (error_page_content) { error_html = error_page_content.value(); } else { - GetContentClient()->renderer()->PrepareErrorPage(this, failed_request, - error, &error_html); + GetContentClient()->renderer()->PrepareErrorPage( + this, error, failed_request.HttpMethod().Ascii(), + failed_request.GetCacheMode() == + blink::mojom::FetchCacheMode::kBypassCache, + &error_html); } // Make sure we never show errors in view source mode. @@ -2904,7 +2914,7 @@ ContextMenuParams our_params(params); blink::WebRect position_in_window(params.x, params.y, 0, 0); - GetRenderWidget()->ConvertViewportToWindow(&position_in_window); + GetLocalRootRenderWidget()->ConvertViewportToWindow(&position_in_window); our_params.x = position_in_window.x; our_params.y = position_in_window.y; @@ -3421,7 +3431,8 @@ if (frame_->GetProvisionalDocumentLoader()) { // TODO(dgozman): why do we need to notify browser in response // to it's own request? - SendFailedProvisionalLoad(failed_request, error, frame_); + SendFailedProvisionalLoad(failed_request.HttpMethod().Ascii(), error, + frame_); } } @@ -3430,11 +3441,17 @@ error_html = error_page_content.value(); // We don't need the actual error page content, but still call this // for any possible side effects. - GetContentClient()->renderer()->PrepareErrorPage(this, failed_request, - error, nullptr); + GetContentClient()->renderer()->PrepareErrorPage( + this, error, failed_request.HttpMethod().Ascii(), + failed_request.GetCacheMode() == + blink::mojom::FetchCacheMode::kBypassCache, + nullptr); } else { - GetContentClient()->renderer()->PrepareErrorPage(this, failed_request, - error, &error_html); + GetContentClient()->renderer()->PrepareErrorPage( + this, error, failed_request.HttpMethod().Ascii(), + failed_request.GetCacheMode() == + blink::mojom::FetchCacheMode::kBypassCache, + &error_html); } // Make sure we never show errors in view source mode. @@ -3668,7 +3685,7 @@ const blink::WebString& sink_id, blink::WebLayerTreeView* layer_tree_view) { const cc::LayerTreeSettings& settings = - GetRenderWidget()->layer_tree_view()->GetLayerTreeSettings(); + GetLocalRootRenderWidget()->layer_tree_view()->GetLayerTreeSettings(); return media_factory_.CreateMediaPlayer(source, client, encrypted_client, initial_cdm, sink_id, layer_tree_view, settings); @@ -3778,11 +3795,8 @@ return NULL; external_popup_menu_.reset( new ExternalPopupMenu(this, popup_menu_info, popup_menu_client)); - if (render_view_->screen_metrics_emulator_) { - render_view_->SetExternalPopupOriginAdjustmentsForEmulation( - external_popup_menu_.get(), - render_view_->screen_metrics_emulator_.get()); - } + render_view_->GetWidget()->SetExternalPopupOriginAdjustmentsForEmulation( + external_popup_menu_.get()); return external_popup_menu_.get(); #else return nullptr; @@ -3977,7 +3991,7 @@ Send(new FrameHostMsg_Detach(routing_id_)); // Clean up the associated RenderWidget for the frame, if there is one. - GetRenderWidget()->UnregisterRenderFrame(this); + GetLocalRootRenderWidget()->UnregisterRenderFrame(this); if (is_main_frame_) { // TODO(crbug.com/419087): The RenderWidget for the main frame can't be // closed/destroyed since it is part of the RenderView. So instead it is @@ -4119,7 +4133,7 @@ } void RenderFrameImpl::SetMouseCapture(bool capture) { - GetRenderWidget()->SetMouseCapture(capture); + GetLocalRootRenderWidget()->SetMouseCapture(capture); } bool RenderFrameImpl::ShouldReportDetailedMessageForSource( @@ -4214,7 +4228,7 @@ TRACE_EVENT2("navigation,benchmark,rail", "RenderFrameImpl::didStartProvisionalLoad", "id", routing_id_, - "url", document_loader->GetRequest().Url().GetString().Utf8()); + "url", document_loader->GetUrl().GetString().Utf8()); NavigationState* navigation_state = NavigationState::FromDocumentLoader(document_loader); @@ -4299,15 +4313,16 @@ // track of that on the widget to help the browser process detect when stale // compositor frames are being shown after a commit. if (is_main_frame_) { - GetRenderWidget()->DidNavigate(); + GetLocalRootRenderWidget()->DidNavigate(); // Update the URL used to key Ukm metrics in the compositor if the // navigation is not in the same document, which represents a new source // URL. // Note that this is only done for the main frame since the metrics for all // frames are keyed to the main frame's URL. - if (GetRenderWidget()->layer_tree_view()) - GetRenderWidget()->layer_tree_view()->SetURLForUkm(GetLoadingUrl()); + if (GetLocalRootRenderWidget()->layer_tree_view()) + GetLocalRootRenderWidget()->layer_tree_view()->SetURLForUkm( + GetLoadingUrl()); } service_manager::mojom::InterfaceProviderRequest @@ -4537,8 +4552,11 @@ WebURL unreachable_url = frame_->GetDocument().Url(); std::string error_html; GetContentClient()->renderer()->PrepareErrorPageForHttpStatusError( - this, document_loader->GetRequest(), unreachable_url, http_status_code, - &error_html); + this, unreachable_url, + document_loader->GetRequest().HttpMethod().Ascii(), + document_loader->GetRequest().GetCacheMode() == + blink::mojom::FetchCacheMode::kBypassCache, + http_status_code, &error_html); // This call may run scripts, e.g. via the beforeunload event, and possibly // delete |this|. LoadNavigationErrorPage(document_loader, @@ -4574,8 +4592,8 @@ const WebURLRequest& failed_request = document_loader->GetRequest(); base::string16 error_description; - GetContentClient()->renderer()->GetErrorDescription(failed_request, error, - &error_description); + GetContentClient()->renderer()->GetErrorDescription( + error, failed_request.HttpMethod().Ascii(), &error_description); Send(new FrameHostMsg_DidFailLoadWithError( routing_id_, failed_request.Url(), error.reason(), error_description)); } @@ -4592,8 +4610,7 @@ observer.DidFinishLoad(); WebDocumentLoader* document_loader = frame_->GetDocumentLoader(); - Send(new FrameHostMsg_DidFinishLoad(routing_id_, - document_loader->GetRequest().Url())); + Send(new FrameHostMsg_DidFinishLoad(routing_id_, document_loader->GetUrl())); if (!RenderThreadImpl::current()) return; @@ -4691,7 +4708,7 @@ } void RenderFrameImpl::DidChangeSelection(bool is_empty_selection) { - if (!GetRenderWidget()->input_handler().handling_input_event() && + if (!GetLocalRootRenderWidget()->input_handler().handling_input_event() && !handling_select_range_) return; @@ -4703,13 +4720,13 @@ // was changed, and SyncSelectionIfRequired may send SelectionChanged // to notify the selection was changed. Focus change should be notified // before selection change. - GetRenderWidget()->UpdateTextInputState(); + GetLocalRootRenderWidget()->UpdateTextInputState(); SyncSelectionIfRequired(); } bool RenderFrameImpl::HandleCurrentKeyboardEvent() { bool did_execute_command = false; - for (auto command : GetRenderWidget()->edit_commands()) { + for (auto command : GetLocalRootRenderWidget()->edit_commands()) { // In gtk and cocoa, it's possible to bind multiple edit commands to one // key (but it's the exception). Once one edit command is not executed, it // seems safest to not execute the rest. @@ -4762,13 +4779,13 @@ void RenderFrameImpl::ShowContextMenu(const blink::WebContextMenuData& data) { ContextMenuParams params = ContextMenuParamsBuilder::Build(data); blink::WebRect position_in_window(params.x, params.y, 0, 0); - GetRenderWidget()->ConvertViewportToWindow(&position_in_window); + GetLocalRootRenderWidget()->ConvertViewportToWindow(&position_in_window); params.x = position_in_window.x; params.y = position_in_window.y; - GetRenderWidget()->OnShowHostContextMenu(¶ms); - if (GetRenderWidget()->has_host_context_menu_location()) { - params.x = GetRenderWidget()->host_context_menu_location().x(); - params.y = GetRenderWidget()->host_context_menu_location().y(); + GetLocalRootRenderWidget()->OnShowHostContextMenu(¶ms); + if (GetLocalRootRenderWidget()->has_host_context_menu_location()) { + params.x = GetLocalRootRenderWidget()->host_context_menu_location().x(); + params.y = GetLocalRootRenderWidget()->host_context_menu_location().y(); } // Serializing a GURL longer than kMaxURLChars will fail, so don't do @@ -4780,7 +4797,7 @@ params.src_url = GURL(); blink::WebRect selection_in_window(data.selection_rect); - GetRenderWidget()->ConvertViewportToWindow(&selection_in_window); + GetLocalRootRenderWidget()->ConvertViewportToWindow(&selection_in_window); params.selection_rect = selection_in_window; #if defined(OS_ANDROID) @@ -5442,7 +5459,7 @@ } bool RenderFrameImpl::IsHidden() { - return GetRenderWidget()->is_hidden(); + return GetLocalRootRenderWidget()->is_hidden(); } bool RenderFrameImpl::IsLocalRoot() const { @@ -5488,7 +5505,7 @@ // resource requests. Once those dependencies are unwound or moved to // RenderFrameHost (https://crbug.com/304341) we can move the client to be // based on the routing_id of the RenderFrameHost. - params->render_view_routing_id = render_view_->routing_id(); + params->render_view_routing_id = render_view_->GetRoutingID(); // "Standard" commits from Blink create new NavigationEntries. We also treat // main frame "inert" commits as creating new NavigationEntries if they @@ -5533,7 +5550,7 @@ // corresponding FrameNavigationEntry. params->page_state = SingleHistoryItemToPageState(current_history_item_); - params->content_source_id = GetRenderWidget()->GetContentSourceId(); + params->content_source_id = GetLocalRootRenderWidget()->GetContentSourceId(); params->method = request.HttpMethod().Latin1(); if (params->method == "POST") @@ -5888,7 +5905,7 @@ // then we won't have to do this. render_view_->GetWidget()->SetIsFrozen(false); } - render_view_->UpdateWebViewWithDeviceScaleFactor(); + render_view_->GetWidget()->UpdateWebViewWithDeviceScaleFactor(); } return true; @@ -5925,7 +5942,7 @@ if (!node.IsNull() && node.IsElementNode()) { WebElement element = const_cast<WebNode&>(node).To<WebElement>(); blink::WebRect rect = element.BoundsInViewport(); - GetRenderWidget()->ConvertViewportToWindow(&rect); + GetLocalRootRenderWidget()->ConvertViewportToWindow(&rect); is_editable = element.IsEditable(); node_bounds = gfx::Rect(rect); } @@ -5933,7 +5950,7 @@ node_bounds)); // Ensures that further text input state can be sent even when previously // focused input and the newly focused input share the exact same state. - GetRenderWidget()->ClearTextInputState(); + GetLocalRootRenderWidget()->ClearTextInputState(); for (auto& observer : observers_) observer.FocusedNodeChanged(node); @@ -6042,7 +6059,7 @@ // subsequent checks. For a popup, the document's URL may become the opener // window's URL if the opener has called document.write(). // See http://crbug.com/93517. - GURL old_url(frame_->GetDocumentLoader()->GetRequest().Url()); + GURL old_url(frame_->GetDocumentLoader()->GetUrl()); // Detect when we're crossing a permission-based boundary (e.g. into or out of // an extension or app origin, leaving a WebUI page, etc). We only care about @@ -6107,12 +6124,6 @@ } } - // When an MHTML Archive is present, it should be used to serve iframe content - // instead of doing a network request. - bool use_archive = (info->archive_status == - blink::WebNavigationInfo::ArchiveStatus::Present) && - !url.SchemeIs(url::kDataScheme); - if (info->navigation_policy == blink::kWebNavigationPolicyCurrentTab) { if (!info->form.IsNull()) { for (auto& observer : observers_) @@ -6121,20 +6132,35 @@ sync_navigation_callback_.Cancel(); - // If the navigation is not synchronous, send it to the browser. This - // includes navigations with no request being sent to the network stack. + // When an MHTML Archive is present, it should be used to serve iframe + // content instead of doing a network request. + bool use_archive = (info->archive_status == + blink::WebNavigationInfo::ArchiveStatus::Present) && + !url.SchemeIs(url::kDataScheme); + + // Navigations which require network request should be sent to the browser. if (!use_archive && IsURLHandledByNetworkStack(url)) { BeginNavigationInternal(std::move(info)); - } else if (WebDocumentLoader::WillLoadUrlAsEmpty(url) && - frame_->HasCommittedFirstRealLoad()) { - sync_navigation_callback_.Reset( - base::BindOnce(&RenderFrameImpl::CommitSyncNavigation, - weak_factory_.GetWeakPtr(), base::Passed(&info))); - frame_->GetTaskRunner(blink::TaskType::kInternalLoading) - ->PostTask(FROM_HERE, sync_navigation_callback_.callback()); - } else { - CommitSyncNavigation(std::move(info)); + return; } + + // First navigaiton in a frame to an empty document must be handled + // synchronously. + if (WebDocumentLoader::WillLoadUrlAsEmpty(url) && + !frame_->HasCommittedFirstRealLoad()) { + CommitSyncNavigation(std::move(info)); + return; + } + + // Everything else (does not require networking, not an empty document) + // will be committed asynchronously in the renderer. + if (!CreatePlaceholderDocumentLoader(*info)) + return; + sync_navigation_callback_.Reset( + base::BindOnce(&RenderFrameImpl::CommitSyncNavigation, + weak_factory_.GetWeakPtr(), base::Passed(&info))); + frame_->GetTaskRunner(blink::TaskType::kInternalLoading) + ->PostTask(FROM_HERE, sync_navigation_callback_.callback()); return; } @@ -6354,7 +6380,7 @@ const gfx::PointF& location, const blink::WebMediaPlayerAction& action) { blink::WebFloatRect viewport_position(location.x(), location.y(), 0, 0); - GetRenderWidget()->ConvertWindowToViewport(&viewport_position); + GetLocalRootRenderWidget()->ConvertWindowToViewport(&viewport_position); frame_->PerformMediaPlayerAction( WebPoint(viewport_position.x, viewport_position.y), action); } @@ -6370,8 +6396,12 @@ return; blink::WebScopedUserGesture gesture(frame_); - external_popup_menu_->DidSelectItem(selected_index); - external_popup_menu_.reset(); + // We need to reset |external_popup_menu_| before calling DidSelectItem(), + // which might delete |this|. + // See ExternalPopupMenuRemoveTest.RemoveFrameOnChange + std::unique_ptr<ExternalPopupMenu> popup; + popup.swap(external_popup_menu_); + popup->DidSelectItem(selected_index); } #else void RenderFrameImpl::OnSelectPopupMenuItems( @@ -6385,8 +6415,12 @@ return; blink::WebScopedUserGesture gesture(frame_); - external_popup_menu_->DidSelectItems(canceled, selected_indices); - external_popup_menu_.reset(); + // We need to reset |external_popup_menu_| before calling DidSelectItems(), + // which might delete |this|. + // See ExternalPopupMenuRemoveTest.RemoveFrameOnChange + std::unique_ptr<ExternalPopupMenu> popup; + popup.swap(external_popup_menu_); + popup->DidSelectItems(canceled, selected_indices); } #endif #endif @@ -6588,7 +6622,7 @@ selection_range_ = range; SetSelectedText(text, offset, range); } - GetRenderWidget()->UpdateSelectionBounds(); + GetLocalRootRenderWidget()->UpdateSelectionBounds(); } void RenderFrameImpl::SetCustomURLLoaderFactory( @@ -6616,7 +6650,9 @@ rect_for_scrolled_focused_editable_node_ = rect; has_scrolled_focused_editable_node_into_rect_ = true; - if (!GetRenderWidget()->layer_tree_view()->HasPendingPageScaleAnimation() && + if (!GetLocalRootRenderWidget() + ->layer_tree_view() + ->HasPendingPageScaleAnimation() && autofill_client) { autofill_client->DidCompleteFocusChangeInFrame(); } @@ -6676,20 +6712,23 @@ } } // namespace -void RenderFrameImpl::BeginNavigationInternal( - std::unique_ptr<blink::WebNavigationInfo> info) { - auto navigation_params = blink::WebNavigationParams::CreateFromInfo(*info); +bool RenderFrameImpl::CreatePlaceholderDocumentLoader( + const blink::WebNavigationInfo& info) { + auto navigation_params = blink::WebNavigationParams::CreateFromInfo(info); // We need the provider to be non-null, otherwise Blink crashes, even though // the provider should not be used for any actual networking. navigation_params->service_worker_network_provider = BuildServiceWorkerNetworkProviderForNavigation( nullptr /* request_params */, nullptr /* controller_service_worker_info */); - if (!frame_->CreatePlaceholderDocumentLoader(std::move(navigation_params), - info->navigation_type, - BuildDocumentState())) { + return frame_->CreatePlaceholderDocumentLoader( + std::move(navigation_params), info.navigation_type, BuildDocumentState()); +} + +void RenderFrameImpl::BeginNavigationInternal( + std::unique_ptr<blink::WebNavigationInfo> info) { + if (!CreatePlaceholderDocumentLoader(*info)) return; - } WebDocumentLoader* document_loader = frame_->GetProvisionalDocumentLoader(); NavigationState* navigation_state = @@ -6852,18 +6891,16 @@ routing_id_, SingleHistoryItemToPageState(current_history_item_))); } -void RenderFrameImpl::SendFailedProvisionalLoad( - const blink::WebURLRequest& request, - const WebURLError& error, - blink::WebLocalFrame* frame) { +void RenderFrameImpl::SendFailedProvisionalLoad(const std::string& http_method, + const WebURLError& error, + blink::WebLocalFrame* frame) { bool show_repost_interstitial = - (error.reason() == net::ERR_CACHE_MISS && - base::EqualsASCII(request.HttpMethod().Utf16(), "POST")); + error.reason() == net::ERR_CACHE_MISS && http_method == "POST"; FrameHostMsg_DidFailProvisionalLoadWithError_Params params; params.error_code = error.reason(); GetContentClient()->renderer()->GetErrorDescription( - request, error, ¶ms.error_description); + error, http_method, ¶ms.error_description); params.url = error.url(), params.showing_repost_interstitial = show_repost_interstitial; Send(new FrameHostMsg_DidFailProvisionalLoadWithError(routing_id_, params)); @@ -6899,8 +6936,7 @@ if (MaybeGetOverriddenURL(document_loader, &overriden_url)) return overriden_url; - const WebURLRequest& request = document_loader->GetRequest(); - return request.Url(); + return document_loader->GetUrl(); } media::MediaPermission* RenderFrameImpl::GetMediaPermission() { @@ -6932,8 +6968,8 @@ char_event.unmodified_text[i - char_start] = text[i]; } - if (GetRenderWidget()->GetWebWidget()) - GetRenderWidget()->GetWebWidget()->HandleInputEvent( + if (GetLocalRootRenderWidget()->GetWebWidget()) + GetLocalRootRenderWidget()->GetWebWidget()->HandleInputEvent( blink::WebCoalescedInputEvent(char_event)); } } else { @@ -7127,8 +7163,8 @@ else if (focused_pepper_plugin_ == instance) focused_pepper_plugin_ = nullptr; - GetRenderWidget()->UpdateTextInputState(); - GetRenderWidget()->UpdateSelectionBounds(); + GetLocalRootRenderWidget()->UpdateTextInputState(); + GetLocalRootRenderWidget()->UpdateSelectionBounds(); } void RenderFrameImpl::PepperStartsPlayback(PepperPluginInstanceImpl* instance) { @@ -7211,7 +7247,7 @@ } void RenderFrameImpl::BindWidget(mojom::WidgetRequest request) { - GetRenderWidget()->SetWidgetBinding(std::move(request)); + GetLocalRootRenderWidget()->SetWidgetBinding(std::move(request)); } blink::WebComputedAXTree* RenderFrameImpl::GetOrCreateWebComputedAXTree() {
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 687d8428..68c2520 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -314,7 +314,7 @@ RendererWebCookieJarImpl* cookie_jar() { return &cookie_jar_; } // Returns the RenderWidget associated with this frame. - RenderWidget* GetRenderWidget(); + RenderWidget* GetLocalRootRenderWidget(); // This method must be called after the frame has been added to the frame // tree. It creates all objects that depend on the frame being at its proper @@ -901,6 +901,7 @@ friend class RenderAccessibilityImplTest; friend class TestRenderFrame; FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuDisplayNoneTest, SelectItem); + FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuRemoveTest, RemoveFrameOnChange); FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuRemoveTest, RemoveOnChange); FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuTest, NormalCase); FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuTest, ShowPopupThenNavigate); @@ -990,6 +991,11 @@ // this returns false and aborts the swap. bool SwapIn(); + // Returns the RenderWidget associated with the main frame. + // TODO(ajwong): This method should go away when cross-frame property setting + // events moves into RenderWidget. + RenderWidget* GetMainFrameRenderWidget(); + // IPC message handlers ------------------------------------------------------ // // The documentation for these functions should be in @@ -1150,6 +1156,10 @@ const GURL& url, const RequestNavigationParams& request_params); + // Creates a placeholder document loader, while navigation is taking place, + // either in the browser or in the renderer. + bool CreatePlaceholderDocumentLoader(const blink::WebNavigationInfo& info); + // Sends a FrameHostMsg_BeginNavigation to the browser void BeginNavigationInternal(std::unique_ptr<blink::WebNavigationInfo> info); @@ -1166,8 +1176,8 @@ GURL* base_url); // Sends a proper FrameHostMsg_DidFailProvisionalLoadWithError_Params IPC for - // the failed request |request|. - void SendFailedProvisionalLoad(const blink::WebURLRequest& request, + // the failed provisional load. + void SendFailedProvisionalLoad(const std::string& http_method, const blink::WebURLError& error, blink::WebLocalFrame* frame);
diff --git a/content/renderer/render_frame_impl_browsertest.cc b/content/renderer/render_frame_impl_browsertest.cc index 8d3ab660..b84b6ca 100644 --- a/content/renderer/render_frame_impl_browsertest.cc +++ b/content/renderer/render_frame_impl_browsertest.cc
@@ -239,7 +239,8 @@ grandchild->in_frame_tree_ = true; grandchild->Initialize(); - EXPECT_EQ(grandchild->GetRenderWidget(), frame()->GetRenderWidget()); + EXPECT_EQ(grandchild->GetLocalRootRenderWidget(), + frame()->GetLocalRootRenderWidget()); RenderFrameTestObserver observer(grandchild);
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index 4c94207..d2daf3b9 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc
@@ -102,7 +102,7 @@ // RenderFrameProxy uses its parent's RenderWidget. RenderWidget* widget = parent_is_local - ? frame_to_replace->GetRenderWidget() + ? frame_to_replace->GetLocalRootRenderWidget() : RenderFrameProxy::FromWebFrame( frame_to_replace->GetWebFrame()->Parent()->ToWebRemoteFrame()) ->render_widget();
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index c01abf5..7e515e057 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -262,10 +262,10 @@ view->GetWidget()->OnEnableDeviceEmulation(params); } - void ReceiveSetTextDirection(RenderViewImpl* view, + void ReceiveSetTextDirection(RenderWidget* widget, blink::WebTextDirection direction) { // Emulates receiving an IPC message. - view->OnSetTextDirection(direction); + widget->OnSetTextDirection(direction); } void GoToOffsetWithParams(int offset, @@ -433,10 +433,8 @@ // the main frame is detached and deleted, and makes sure the view does not // leak. void CloseRenderView(RenderViewImpl* new_view) { - new_view->Close(); + new_view->GetWidget()->Close(); EXPECT_FALSE(new_view->GetMainRenderFrame()); - - new_view->Release(); } private: @@ -477,20 +475,22 @@ visual_properties.new_size = gfx::Size(100, 100); visual_properties.compositor_viewport_pixel_size = gfx::Size(200, 200); visual_properties.visible_viewport_size = visual_properties.new_size; - visual_properties.auto_resize_enabled = view()->auto_resize_mode(); + visual_properties.auto_resize_enabled = + view()->GetWidget()->auto_resize_mode(); visual_properties.capture_sequence_number = - view()->capture_sequence_number(); + view()->GetWidget()->capture_sequence_number(); visual_properties.min_size_for_auto_resize = - view()->min_size_for_auto_resize(); + view()->GetWidget()->min_size_for_auto_resize(); visual_properties.max_size_for_auto_resize = - view()->max_size_for_auto_resize(); + view()->GetWidget()->max_size_for_auto_resize(); visual_properties.local_surface_id_allocation = viz::LocalSurfaceIdAllocation( viz::LocalSurfaceId(1, 1, base::UnguessableToken::Create()), base::TimeTicks::Now()); - view()->OnSynchronizeVisualProperties(visual_properties); - ASSERT_EQ(dsf, view()->GetWebScreenInfo().device_scale_factor); - ASSERT_EQ(dsf, view()->GetOriginalScreenInfo().device_scale_factor); + view()->GetWidget()->OnSynchronizeVisualProperties(visual_properties); + ASSERT_EQ(dsf, view()->GetWidget()->GetWebScreenInfo().device_scale_factor); + ASSERT_EQ(dsf, + view()->GetWidget()->GetOriginalScreenInfo().device_scale_factor); } void TestEmulatedSizeDprDsf(int width, int height, float dpr, @@ -516,7 +516,8 @@ EXPECT_EQ(height, emulated_height); EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(get_dpr, &emulated_dpr)); EXPECT_EQ(static_cast<int>(dpr * 10), emulated_dpr); - cc::LayerTreeHost* host = view()->layer_tree_view()->layer_tree_host(); + cc::LayerTreeHost* host = + view()->GetWidget()->layer_tree_view()->layer_tree_host(); EXPECT_EQ(compositor_dsf, host->device_scale_factor()); } }; @@ -838,9 +839,8 @@ GURL blank_url("about:blank"); LoadHTMLWithUrlOverride("<body></body", example_url.spec().c_str()); - EXPECT_EQ( - example_url, - GURL(frame()->GetWebFrame()->GetDocumentLoader()->GetRequest().Url())); + EXPECT_EQ(example_url, + GURL(frame()->GetWebFrame()->GetDocumentLoader()->GetUrl())); // Empty url should never fork. auto navigation_info = std::make_unique<blink::WebNavigationInfo>(); @@ -856,9 +856,8 @@ GURL blank_url("about:blank"); LoadHTMLWithUrlOverride("<body></body", example_url.spec().c_str()); - EXPECT_EQ( - example_url, - GURL(frame()->GetWebFrame()->GetDocumentLoader()->GetRequest().Url())); + EXPECT_EQ(example_url, + GURL(frame()->GetWebFrame()->GetDocumentLoader()->GetUrl())); // About blank should never fork. auto navigation_info = std::make_unique<blink::WebNavigationInfo>(); @@ -1255,7 +1254,7 @@ // Update the IME status and verify if our IME backend sends an IPC message // to activate IMEs. - view()->UpdateTextInputState(); + view()->GetWidget()->UpdateTextInputState(); const IPC::Message* msg = render_thread_->sink().GetMessageAt(0); EXPECT_TRUE(msg != nullptr); EXPECT_EQ(static_cast<uint32_t>(WidgetHostMsg_TextInputStateChanged::ID), @@ -1277,7 +1276,7 @@ // Update the IME status and verify if our IME backend sends an IPC message // to de-activate IMEs. - view()->UpdateTextInputState(); + view()->GetWidget()->UpdateTextInputState(); msg = render_thread_->sink().GetMessageAt(0); EXPECT_TRUE(msg != nullptr); EXPECT_EQ(static_cast<uint32_t>(WidgetHostMsg_TextInputStateChanged::ID), @@ -1302,7 +1301,7 @@ // Update the IME status and verify if our IME backend sends an IPC // message to activate IMEs. - view()->UpdateTextInputState(); + view()->GetWidget()->UpdateTextInputState(); base::RunLoop().RunUntilIdle(); const IPC::Message* msg = render_thread_->sink().GetMessageAt(0); EXPECT_TRUE(msg != nullptr); @@ -1410,36 +1409,37 @@ case IME_SETFOCUS: // Update the window focus. - view()->OnSetFocus(ime_message->enable); + view()->GetWidget()->OnSetFocus(ime_message->enable); break; case IME_SETCOMPOSITION: - view()->OnImeSetComposition( + view()->GetWidget()->OnImeSetComposition( base::WideToUTF16(ime_message->ime_string), std::vector<blink::WebImeTextSpan>(), gfx::Range::InvalidRange(), ime_message->selection_start, ime_message->selection_end); break; case IME_COMMITTEXT: - view()->OnImeCommitText(base::WideToUTF16(ime_message->ime_string), - std::vector<blink::WebImeTextSpan>(), - gfx::Range::InvalidRange(), 0); + view()->GetWidget()->OnImeCommitText( + base::WideToUTF16(ime_message->ime_string), + std::vector<blink::WebImeTextSpan>(), gfx::Range::InvalidRange(), + 0); break; case IME_FINISHCOMPOSINGTEXT: - view()->OnImeFinishComposingText(false); + view()->GetWidget()->OnImeFinishComposingText(false); break; case IME_CANCELCOMPOSITION: - view()->OnImeSetComposition(base::string16(), - std::vector<blink::WebImeTextSpan>(), - gfx::Range::InvalidRange(), 0, 0); + view()->GetWidget()->OnImeSetComposition( + base::string16(), std::vector<blink::WebImeTextSpan>(), + gfx::Range::InvalidRange(), 0, 0); break; } // Update the status of our IME back-end. // TODO(hbono): we should verify messages to be sent from the back-end. - view()->UpdateTextInputState(); + view()->GetWidget()->UpdateTextInputState(); base::RunLoop().RunUntilIdle(); render_thread_->sink().ClearMessages(); @@ -1482,7 +1482,7 @@ for (size_t i = 0; i < arraysize(kTextDirection); ++i) { // Set the text direction of the <textarea> element. ExecuteJavaScriptForTests("document.getElementById('test').focus();"); - ReceiveSetTextDirection(view(), kTextDirection[i].direction); + ReceiveSetTextDirection(view()->GetWidget(), kTextDirection[i].direction); // Write the values of its DOM 'dir' attribute and its CSS 'direction' // property to the <div> element. @@ -1696,43 +1696,46 @@ const base::string16 empty_string; const std::vector<blink::WebImeTextSpan> empty_ime_text_span; std::vector<gfx::Rect> bounds; - view()->OnSetFocus(true); + view()->GetWidget()->OnSetFocus(true); // ASCII composition const base::string16 ascii_composition = base::UTF8ToUTF16("aiueo"); - view()->OnImeSetComposition(ascii_composition, empty_ime_text_span, - gfx::Range::InvalidRange(), 0, 0); - view()->GetCompositionCharacterBounds(&bounds); + view()->GetWidget()->OnImeSetComposition( + ascii_composition, empty_ime_text_span, gfx::Range::InvalidRange(), 0, 0); + view()->GetWidget()->GetCompositionCharacterBounds(&bounds); ASSERT_EQ(ascii_composition.size(), bounds.size()); for (size_t i = 0; i < bounds.size(); ++i) EXPECT_LT(0, bounds[i].width()); - view()->OnImeCommitText(empty_string, std::vector<blink::WebImeTextSpan>(), - gfx::Range::InvalidRange(), 0); + view()->GetWidget()->OnImeCommitText(empty_string, + std::vector<blink::WebImeTextSpan>(), + gfx::Range::InvalidRange(), 0); // Non surrogate pair unicode character. const base::string16 unicode_composition = base::UTF8ToUTF16( "\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A"); - view()->OnImeSetComposition(unicode_composition, empty_ime_text_span, - gfx::Range::InvalidRange(), 0, 0); - view()->GetCompositionCharacterBounds(&bounds); + view()->GetWidget()->OnImeSetComposition(unicode_composition, + empty_ime_text_span, + gfx::Range::InvalidRange(), 0, 0); + view()->GetWidget()->GetCompositionCharacterBounds(&bounds); ASSERT_EQ(unicode_composition.size(), bounds.size()); for (size_t i = 0; i < bounds.size(); ++i) EXPECT_LT(0, bounds[i].width()); - view()->OnImeCommitText(empty_string, empty_ime_text_span, - gfx::Range::InvalidRange(), 0); + view()->GetWidget()->OnImeCommitText(empty_string, empty_ime_text_span, + gfx::Range::InvalidRange(), 0); // Surrogate pair character. const base::string16 surrogate_pair_char = base::UTF8ToUTF16("\xF0\xA0\xAE\x9F"); - view()->OnImeSetComposition(surrogate_pair_char, empty_ime_text_span, - gfx::Range::InvalidRange(), 0, 0); - view()->GetCompositionCharacterBounds(&bounds); + view()->GetWidget()->OnImeSetComposition(surrogate_pair_char, + empty_ime_text_span, + gfx::Range::InvalidRange(), 0, 0); + view()->GetWidget()->GetCompositionCharacterBounds(&bounds); ASSERT_EQ(surrogate_pair_char.size(), bounds.size()); EXPECT_LT(0, bounds[0].width()); EXPECT_EQ(0, bounds[1].width()); - view()->OnImeCommitText(empty_string, empty_ime_text_span, - gfx::Range::InvalidRange(), 0); + view()->GetWidget()->OnImeCommitText(empty_string, empty_ime_text_span, + gfx::Range::InvalidRange(), 0); // Mixed string. const base::string16 surrogate_pair_mixed_composition = @@ -1741,10 +1744,10 @@ const size_t utf16_length = 8UL; const bool is_surrogate_pair_empty_rect[8] = { false, true, false, false, true, false, false, true }; - view()->OnImeSetComposition(surrogate_pair_mixed_composition, - empty_ime_text_span, gfx::Range::InvalidRange(), - 0, 0); - view()->GetCompositionCharacterBounds(&bounds); + view()->GetWidget()->OnImeSetComposition(surrogate_pair_mixed_composition, + empty_ime_text_span, + gfx::Range::InvalidRange(), 0, 0); + view()->GetWidget()->GetCompositionCharacterBounds(&bounds); ASSERT_EQ(utf16_length, bounds.size()); for (size_t i = 0; i < utf16_length; ++i) { if (is_surrogate_pair_empty_rect[i]) { @@ -1753,8 +1756,8 @@ EXPECT_LT(0, bounds[i].width()); } } - view()->OnImeCommitText(empty_string, empty_ime_text_span, - gfx::Range::InvalidRange(), 0); + view()->GetWidget()->OnImeCommitText(empty_string, empty_ime_text_span, + gfx::Range::InvalidRange(), 0); } #endif @@ -1992,18 +1995,20 @@ } void PrepareErrorPage(content::RenderFrame* render_frame, - const blink::WebURLRequest& failed_request, const blink::WebURLError& error, + const std::string& http_method, + bool ignoring_cache, std::string* error_html) override { if (error_html) *error_html = "A suffusion of yellow."; } - void PrepareErrorPageForHttpStatusError( - content::RenderFrame* render_frame, - const blink::WebURLRequest& failed_request, - const GURL& url, - int http_status_code, - std::string* error_html) override { + + void PrepareErrorPageForHttpStatusError(content::RenderFrame* render_frame, + const GURL& unreachable_url, + const std::string& http_method, + bool ignoring_cache, + int http_status, + std::string* error_html) override { if (error_html) *error_html = "A suffusion of yellow."; } @@ -2727,18 +2732,18 @@ const base::string16 empty_string; const std::vector<blink::WebImeTextSpan> empty_ime_text_span; std::vector<gfx::Rect> bounds_at_1x; - view()->OnSetFocus(true); + view()->GetWidget()->OnSetFocus(true); // ASCII composition const base::string16 ascii_composition = base::UTF8ToUTF16("aiueo"); - view()->OnImeSetComposition(ascii_composition, empty_ime_text_span, - gfx::Range::InvalidRange(), 0, 0); - view()->GetCompositionCharacterBounds(&bounds_at_1x); + view()->GetWidget()->OnImeSetComposition( + ascii_composition, empty_ime_text_span, gfx::Range::InvalidRange(), 0, 0); + view()->GetWidget()->GetCompositionCharacterBounds(&bounds_at_1x); ASSERT_EQ(ascii_composition.size(), bounds_at_1x.size()); SetDeviceScaleFactor(2.f); std::vector<gfx::Rect> bounds_at_2x; - view()->GetCompositionCharacterBounds(&bounds_at_2x); + view()->GetWidget()->GetCompositionCharacterBounds(&bounds_at_2x); ASSERT_EQ(bounds_at_1x.size(), bounds_at_2x.size()); for (size_t i = 0; i < bounds_at_1x.size(); i++) { const gfx::Rect& b1 = bounds_at_1x[i];
diff --git a/content/renderer/render_view_browsertest_mac.mm b/content/renderer/render_view_browsertest_mac.mm index 19778ed3..535c15a 100644 --- a/content/renderer/render_view_browsertest_mac.mm +++ b/content/renderer/render_view_browsertest_mac.mm
@@ -97,7 +97,7 @@ render_thread_->sink().ClearMessages(); const char* kArrowDownScrollDown = "40,false,false,true,false\n9844"; - view->OnSetEditCommandsForNextKeyEvent( + view->GetWidget()->OnSetEditCommandsForNextKeyEvent( EditCommands(1, EditCommand("moveToEndOfDocument", ""))); SendNativeKeyEvent(NativeWebKeyboardEvent(arrowDownKeyDown)); base::RunLoop().RunUntilIdle(); @@ -108,7 +108,7 @@ EXPECT_EQ(kArrowDownScrollDown, output); const char* kArrowUpScrollUp = "38,false,false,true,false\n0"; - view->OnSetEditCommandsForNextKeyEvent( + view->GetWidget()->OnSetEditCommandsForNextKeyEvent( EditCommands(1, EditCommand("moveToBeginningOfDocument", ""))); SendNativeKeyEvent(NativeWebKeyboardEvent(arrowUpKeyDown)); base::RunLoop().RunUntilIdle(); @@ -124,7 +124,7 @@ ExecuteJavaScriptForTests("allowKeyEvents = false; window.scrollTo(0, 100)"); const char* kArrowDownNoScroll = "40,false,false,true,false\n100"; - view->OnSetEditCommandsForNextKeyEvent( + view->GetWidget()->OnSetEditCommandsForNextKeyEvent( EditCommands(1, EditCommand("moveToEndOfDocument", ""))); SendNativeKeyEvent(NativeWebKeyboardEvent(arrowDownKeyDown)); base::RunLoop().RunUntilIdle(); @@ -135,7 +135,7 @@ EXPECT_EQ(kArrowDownNoScroll, output); const char* kArrowUpNoScroll = "38,false,false,true,false\n100"; - view->OnSetEditCommandsForNextKeyEvent( + view->GetWidget()->OnSetEditCommandsForNextKeyEvent( EditCommands(1, EditCommand("moveToBeginningOfDocument", ""))); SendNativeKeyEvent(NativeWebKeyboardEvent(arrowUpKeyDown)); base::RunLoop().RunUntilIdle();
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 5cc21191..b6e7665 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -430,14 +430,14 @@ RenderViewImpl::RenderViewImpl(CompositorDependencies* compositor_deps, const mojom::CreateViewParams& params) - : RenderWidget( + : render_widget_(new RenderWidget( params.main_frame_widget_routing_id, compositor_deps, params.visual_properties.screen_info, params.visual_properties.display_mode, /*is_frozen=*/params.main_frame_routing_id == MSG_ROUTING_NONE, params.hidden, - params.never_visible), + params.never_visible)), routing_id_(params.view_id), renderer_wide_named_frame_lookup_( params.renderer_wide_named_frame_lookup), @@ -446,7 +446,14 @@ weak_ptr_factory_(this) { DCHECK(!session_storage_namespace_id_.empty()) << "Session storage namespace must be populated."; - GetWidget()->set_owner_delegate(this); + + // RenderView used to inherit from RenderWidget. Creating a delegate + // interface and explicitly passing ownership of ourselves to the + // RenderWidget preserves the lifetime semantics. This is a stepping + // stone to having RenderWidget creation taken out of the RenderViewImpl + // constructor. See the corresponding explicit reset() of the delegate + // in the ~RenderWidget(). Also, I hate inheritance. + GetWidget()->set_delegate(base::WrapUnique(this)); RenderThread::Get()->AddRoute(routing_id_, this); } @@ -466,7 +473,7 @@ webview_ = WebView::Create(this, WidgetClient(), params->hidden, /*compositing_enabled=*/true, opener_frame ? opener_frame->View() : nullptr); - RenderWidget::Init(std::move(show_callback), webview_->MainFrameWidget()); + GetWidget()->Init(std::move(show_callback), webview_->MainFrameWidget()); g_view_map.Get().insert(std::make_pair(webview(), this)); g_routing_id_view_map.Get().insert(std::make_pair(GetRoutingID(), this)); @@ -544,9 +551,9 @@ if (params->window_was_created_with_opener) webview()->SetOpenedByDOM(); - UpdateWebViewWithDeviceScaleFactor(); + GetWidget()->UpdateWebViewWithDeviceScaleFactor(); OnSetRendererPrefs(params->renderer_preferences); - OnSynchronizeVisualProperties(params->visual_properties); + GetWidget()->OnSynchronizeVisualProperties(params->visual_properties); GetContentClient()->renderer()->RenderViewCreated(this); page_zoom_level_ = 0; @@ -1118,7 +1125,7 @@ void RenderViewImpl::DidReceiveSetFocusEventForWidget() { // This message must always be received when the main frame is a // WebLocalFrame. - // TODO(ajwong): Can this be removed and just check |owner_delegate_| in + // TODO(ajwong): Can this be removed and just check |delegate_| in // RenderWidget instead? CHECK(webview()->MainFrame()->IsWebLocalFrame()); } @@ -1278,8 +1285,9 @@ // Adding a new message? Add platform independent ones first, then put the // platform specific ones at the end. - // Have the super handle all other messages. - IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message)) + // Have the widget handle all other messages. + // TODO(ajwong): Remove this cross-object dispatch. + IPC_MESSAGE_UNHANDLED(handled = GetWidget()->OnMessageReceived(message)) IPC_END_MESSAGE_MAP() return handled; @@ -1687,7 +1695,10 @@ } blink::WebWidgetClient* RenderViewImpl::WidgetClient() { - return this; + // TODO(ajwong): Remove this API and force clients to get the + // WebWidgetClient through GetWidget(). + // https://crbug.com/545684 + return render_widget_; } // blink::WebLocalFrameClient @@ -1784,11 +1795,18 @@ // override of IPC::Sender, so this method also overrides RenderWidget. Thus // we must call to the base class, not via an upcast or virtual dispatch would // go back here. - return RenderWidget::Send(message); + CHECK(message->routing_id() != MSG_ROUTING_NONE); + + // TODO(ajwong): Don't delegate to render widget. Filter here. + return GetWidget()->Send(message); } RenderWidget* RenderViewImpl::GetWidget() { - return this; + return render_widget_; +} + +const RenderWidget* RenderViewImpl::GetWidget() const { + return render_widget_; } RenderFrameImpl* RenderViewImpl::GetMainRenderFrame() { @@ -1800,11 +1818,11 @@ } gfx::Size RenderViewImpl::GetSize() { - return size(); + return GetWidget()->size(); } float RenderViewImpl::GetDeviceScaleFactor() { - return GetWebScreenInfo().device_scale_factor; + return GetWidget()->GetWebScreenInfo().device_scale_factor; } float RenderViewImpl::GetZoomLevel() { @@ -2121,16 +2139,16 @@ if (webview()->MainFrame()->IsWebRemoteFrame()) return; - if (enable == has_focus()) + if (enable == GetWidget()->has_focus()) return; if (enable) { SetActiveForWidget(true); // Fake an IPC message so go through the IPC handler. - OnSetFocus(true); + GetWidget()->OnSetFocus(true); } else { // Fake an IPC message so go through the IPC handler. - OnSetFocus(false); + GetWidget()->OnSetFocus(false); SetActiveForWidget(false); } }
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index c4b2e8c2..112e20f 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h
@@ -37,7 +37,7 @@ #include "content/public/renderer/render_view.h" #include "content/renderer/render_frame_impl.h" #include "content/renderer/render_widget.h" -#include "content/renderer/render_widget_owner_delegate.h" +#include "content/renderer/render_widget_delegate.h" #include "ipc/ipc_platform_file.h" #include "mojo/public/cpp/bindings/interface_ptr_set.h" #include "third_party/blink/public/common/dom_storage/session_storage_namespace_id.h" @@ -100,12 +100,18 @@ // a local frame for this view, then it also manages a RenderWidget for the // main frame. // -// TODO(419087): That RenderWidget should be managed by the main frame itself. -class CONTENT_EXPORT RenderViewImpl : private RenderWidget, - public blink::WebViewClient, - public RenderWidgetOwnerDelegate, +// TODO(419087): Currently even though the RenderViewImpl "manages" the +// RenderWidget, the RenderWidget owns the RenderViewImpl. This is due to +// RenderViewImpl historically being a subclass of RenderWidget. Breaking +// the ownership relation will require moving the RenderWidget to the main +// frame and updating all the blink objects to understand the lifetime changes. +class CONTENT_EXPORT RenderViewImpl : public blink::WebViewClient, + public IPC::Listener, + public RenderWidgetDelegate, public RenderView { public: + ~RenderViewImpl() override; + // Creates a new RenderView. Note that if the original opener has been closed, // |params.window_was_created_with_opener| will be true and // |params.opener_frame_route_id| will be MSG_ROUTING_NONE. @@ -137,6 +143,7 @@ // Returns the RenderWidget for this RenderView. RenderWidget* GetWidget(); + const RenderWidget* GetWidget() const; const WebPreferences& webkit_preferences() const { return webkit_preferences_; @@ -308,9 +315,6 @@ RenderWidget::ShowCallback show_callback, scoped_refptr<base::SingleThreadTaskRunner> task_runner); - // Do not delete directly. This class is reference counted. - ~RenderViewImpl() override; - // Called when Page visibility is changed, to update the View/Page in blink. // This is separate from the IPC handlers as tests may call this and need to // be able to specify |initial_setting| where IPC handlers do not. @@ -380,10 +384,7 @@ CONNECTION_ERROR, }; - // RenderWidget public API that should no longer go through RenderView. - using RenderWidget::routing_id; - - // RenderWidgetOwnerDelegate implementation ---------------------------------- + // RenderWidgetDelegate implementation ---------------------------------- blink::WebWidget* GetWebWidgetForWidget() const override; blink::WebWidgetClient* GetWebWidgetClientForWidget() override; @@ -519,6 +520,8 @@ // it in the same order in the .cc file as it was in the header. // --------------------------------------------------------------------------- + RenderWidget* render_widget_; + // Routing ID that allows us to communicate with the corresponding // RenderViewHost in the parent browser process. const int32_t routing_id_;
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 97ca49f2..baf77e0 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -71,7 +71,6 @@ #include "content/renderer/render_process.h" #include "content/renderer/render_thread_impl.h" #include "content/renderer/render_view_impl.h" -#include "content/renderer/render_widget_owner_delegate.h" #include "content/renderer/renderer_blink_platform_impl.h" #include "content/renderer/resizing_mode_selector.h" #include "gpu/command_buffer/service/gpu_switches.h" @@ -387,7 +386,6 @@ : routing_id_(widget_routing_id), compositor_deps_(compositor_deps), webwidget_internal_(nullptr), - owner_delegate_(nullptr), auto_resize_mode_(false), is_hidden_(hidden), compositor_never_visible_(never_visible), @@ -443,6 +441,13 @@ RenderWidget::~RenderWidget() { DCHECK(!webwidget_internal_) << "Leaking our WebWidget!"; + + // TODO(ajwong): Test if this actually has to be reset here + // or if it is okay to tear down later in the destructor. This + // would allow for removing the ordering constraint in teardown. + // https://crbug.com/545684 + delegate_.reset(); + // TODO(ajwong): Add in check that routing_id_ has been removed from // g_routing_id_widget_map once the shutdown semantics for RenderWidget // and RenderViewImpl are rationalized. Currently, too many unit and @@ -556,9 +561,9 @@ #if BUILDFLAG(USE_EXTERNAL_POPUP_MENU) void RenderWidget::SetExternalPopupOriginAdjustmentsForEmulation( - ExternalPopupMenu* popup, - RenderWidgetScreenMetricsEmulator* emulator) { - popup->SetOriginScaleForEmulation(emulator->scale()); + ExternalPopupMenu* popup) { + if (screen_metrics_emulator_) + popup->SetOriginScaleForEmulation(screen_metrics_emulator_->scale()); } #endif @@ -640,7 +645,7 @@ } bool RenderWidget::ShouldHandleImeEvents() const { - if (owner_delegate_) + if (delegate()) return has_focus_; if (for_child_local_root_frame_) { // TODO(ekaramad): We track page focus in all RenderViews on the page but @@ -702,12 +707,12 @@ TRACE_EVENT0("renderer", "RenderWidget::OnSynchronizeVisualProperties"); VisualProperties params = original_params; - if (owner_delegate_) { - owner_delegate_->ApplyNewSizeForWidget(size_, params.new_size); + if (delegate()) { + delegate()->ApplyNewSizeForWidget(size_, params.new_size); if (display_mode_ != params.display_mode) { display_mode_ = params.display_mode; - owner_delegate_->ApplyNewDisplayModeForWidget(params.display_mode); + delegate()->ApplyNewDisplayModeForWidget(params.display_mode); } bool auto_resize_mode_changed = @@ -725,10 +730,9 @@ max_auto_size = gfx::ScaleToCeiledSize( max_auto_size, params.screen_info.device_scale_factor); } - owner_delegate_->ApplyAutoResizeLimitsForWidget(min_auto_size, - max_auto_size); + delegate()->ApplyAutoResizeLimitsForWidget(min_auto_size, max_auto_size); } else if (auto_resize_mode_changed) { - owner_delegate_->DisableAutoResizeForWidget(); + delegate()->DisableAutoResizeForWidget(); if (params.new_size.IsEmpty()) return; } @@ -762,8 +766,8 @@ } } - if (owner_delegate_ && params.scroll_focused_node_into_view) - owner_delegate_->ScrollFocusedNodeIntoViewForWidget(); + if (delegate() && params.scroll_focused_node_into_view) + delegate()->ScrollFocusedNodeIntoViewForWidget(); } void RenderWidget::OnEnableDeviceEmulation( @@ -856,7 +860,7 @@ const blink::WebCoalescedInputEvent& input_event, const ui::LatencyInfo& latency_info, HandledEventCallback callback) { - if (owner_delegate_ && is_frozen_) { + if (delegate() && is_frozen_) { std::move(callback).Run(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, latency_info, nullptr, base::nullopt); return; @@ -885,17 +889,17 @@ } void RenderWidget::OnSetActive(bool active) { - if (owner_delegate_) - owner_delegate_->SetActiveForWidget(active); + if (delegate()) + delegate()->SetActiveForWidget(active); } void RenderWidget::OnSetBackgroundOpaque(bool opaque) { // This IPC never sent when frozen. DCHECK(!is_frozen_); // Background opaque-ness modification is only supported for the main frame. - // The |owner_delegate_| is used as proxy for this RenderWidget being attached + // The delegate() is used as proxy for this RenderWidget being attached // to the main frame. - if (!owner_delegate_) + if (!delegate()) return; blink::WebFrameWidget* web_frame_widget = GetFrameWidget(); @@ -909,8 +913,8 @@ } void RenderWidget::OnSetFocus(bool enable) { - if (owner_delegate_) - owner_delegate_->DidReceiveSetFocusEventForWidget(); + if (delegate()) + delegate()->DidReceiveSetFocusEventForWidget(); SetFocus(enable); } @@ -923,15 +927,15 @@ for (auto& observer : render_frames_) observer.RenderWidgetSetFocus(enable); - if (owner_delegate_) - owner_delegate_->DidChangeFocusForWidget(); + if (delegate()) + delegate()->DidChangeFocusForWidget(); } void RenderWidget::SetNeedsMainFrame() { // The WebWidgetClient is not |this| if tests override it for the WebView and // WebViewClient. blink::WebWidgetClient* client = - owner_delegate_ ? owner_delegate_->GetWebWidgetClientForWidget() : this; + delegate() ? delegate()->GetWebWidgetClientForWidget() : this; client->ScheduleAnimation(); } @@ -1038,13 +1042,13 @@ } void RenderWidget::DidCommitCompositorFrame() { - if (owner_delegate_) - owner_delegate_->DidCommitCompositorFrameForWidget(); + if (delegate()) + delegate()->DidCommitCompositorFrameForWidget(); } void RenderWidget::DidCompletePageScaleAnimation() { - if (owner_delegate_) - owner_delegate_->DidCompletePageScaleAnimationForWidget(); + if (delegate()) + delegate()->DidCompletePageScaleAnimationForWidget(); } void RenderWidget::ScheduleAnimation() { @@ -1294,8 +1298,8 @@ possible_drag_event_info_.event_location = gfx::Point(event.PositionInScreen().x, event.PositionInScreen().y); - if (owner_delegate_) - return owner_delegate_->RenderWidgetWillHandleMouseEventForWidget(event); + if (delegate()) + return delegate()->RenderWidgetWillHandleMouseEventForWidget(event); return false; } @@ -1310,10 +1314,10 @@ void RenderWidget::ResizeWebWidget() { gfx::Size size = GetSizeForWebWidget(); - if (owner_delegate_) { - owner_delegate_->ResizeWebWidgetForWidget( - size, top_controls_height_, bottom_controls_height_, - browser_controls_shrink_blink_size_); + if (delegate()) { + delegate()->ResizeWebWidgetForWidget(size, top_controls_height_, + bottom_controls_height_, + browser_controls_shrink_blink_size_); return; } GetWebWidget()->Resize(size); @@ -1361,7 +1365,7 @@ return; // Only propagate the external PSF to non-main-frames. - if (!owner_delegate_) + if (!delegate()) layer_tree_view_->SetExternalPageScaleFactor(params.page_scale_factor); gfx::Size new_compositor_viewport_pixel_size = @@ -1411,7 +1415,7 @@ DidToggleFullscreen(); } - if (!owner_delegate_) { + if (!delegate()) { // Make sure that page scale factor changes propagating down from the main // frame are relayed to nested OOPIFs/non-main-frames. page_scale_factor_from_mainframe_ = params.page_scale_factor; @@ -1423,10 +1427,9 @@ void RenderWidget::SetScreenMetricsEmulationParameters( bool enabled, const blink::WebDeviceEmulationParams& params) { - // This is only supported in RenderView, which has an |owner_delegate_|. - DCHECK(owner_delegate_); - owner_delegate_->SetScreenMetricsEmulationParametersForWidget(enabled, - params); + // This is only supported in RenderView, which has an delegate(). + DCHECK(delegate()); + delegate()->SetScreenMetricsEmulationParametersForWidget(enabled, params); } void RenderWidget::SetScreenRects(const gfx::Rect& widget_screen_rect, @@ -1519,12 +1522,12 @@ // void RenderWidget::Show(WebNavigationPolicy policy) { if (!show_callback_) { - if (owner_delegate_) { + if (delegate()) { // When SupportsMultipleWindows is disabled, popups are reusing // the view's RenderWidget. In some scenarios, this makes blink to call // Show() twice. But otherwise, if it is enabled, we should not visit // Show() more than once. - DCHECK(!owner_delegate_->SupportsMultipleWindowsForWidget()); + DCHECK(!delegate()->SupportsMultipleWindowsForWidget()); return; } else { NOTREACHED() << "received extraneous Show call"; @@ -1703,8 +1706,8 @@ CloseWebWidget(); layer_tree_view_.reset(); - if (owner_delegate_) - owner_delegate_->DidCloseWidget(); + if (delegate()) + delegate()->DidCloseWidget(); // Note the ACK is a control message going to the RenderProcessHost. RenderThread::Get()->Send(new WidgetHostMsg_Close_ACK(routing_id())); } @@ -1719,7 +1722,7 @@ // that would be alive while the IPC route is active such as the // |layer_tree_view_|. So we ensure that it is the first thing to be // destroyed here before deleting things from the RenderWidget or the - // |owner_delegate_|. + // delegate(). // // TODO(danakj): The emulator could reset to non-emulated values in an // explicit method call (instead of in the destructor) that occurs when @@ -1730,14 +1733,14 @@ // Informs the WebWidget that compositor is being destroyed, so it can remove // references to it first. // - // When |owner_delegate_| is present, the RenderWidget is for a main frame, + // When delegate() is present, the RenderWidget is for a main frame, // and the GetWebWidget() is not the same as |webwidget_internal_|. However // that widget is responsible for doing WillCloseLayerTreeView() on the // |webwidget_internal_|, not us. Otherwise, they are the same and this is // notifying |webwidget_internal_|. GetWebWidget()->WillCloseLayerTreeView(); - // While the wrapping WebWidget from an |owner_delegate_| is responsible for + // While the wrapping WebWidget from an delegate() is responsible for // doing WillCloseLayerTreeView() on the |webwidget_internal_|, this class is // responsible for calling Close() on it. Notably, then, the wrapping // WebWidget does not. @@ -1773,14 +1776,14 @@ return nullptr; blink::WebWidget* widget; - if (owner_delegate_) { + if (delegate()) { // Main frame WebFrameWidgets are held by the delegate, the internal widget // points directly to the WebView. // TODO(ekaramad): We should drop IPCs when |is_frozen_| instead of // handling them and finding a null here. However there is also the case // of the frame being detached without the widget being frozen to be // resolved (https://crbug.com/906340). So for now this can return null. - widget = owner_delegate_->GetWebWidgetForWidget(); + widget = delegate()->GetWebWidgetForWidget(); } else { // Subframes always have a WebFrameWidget themselves. widget = webwidget_internal_; @@ -2520,7 +2523,7 @@ void RenderWidget::DidHandleGestureEvent(const WebGestureEvent& event, bool event_cancelled) { if (event_cancelled) { - // The |owner_delegate_| doesn't need to hear about cancelled events. + // The delegate() doesn't need to hear about cancelled events. return; } @@ -2551,9 +2554,9 @@ #endif #endif - // The |owner_delegate_| gets to respond to handling gestures last. - if (owner_delegate_) - owner_delegate_->DidHandleGestureEventForWidget(event); + // The delegate() gets to respond to handling gestures last. + if (delegate()) + delegate()->DidHandleGestureEventForWidget(event); } void RenderWidget::DidOverscroll( @@ -3035,7 +3038,7 @@ const blink::WebPoint& point, const blink::WebRect& rect_to_zoom) { // Only oopif subframes should be sending this message. - DCHECK(!owner_delegate_); + DCHECK(!delegate()); Send(new WidgetHostMsg_AnimateDoubleTapZoomInMainFrame(routing_id(), point, rect_to_zoom)); } @@ -3043,7 +3046,7 @@ void RenderWidget::ZoomToFindInPageRectInMainFrame( const blink::WebRect& rect_to_zoom) { // Only oopif subframes should be sending this message. - DCHECK(!owner_delegate_); + DCHECK(!delegate_); Send(new WidgetHostMsg_ZoomToFindInPageRectInMainFrame(routing_id(), rect_to_zoom)); } @@ -3158,9 +3161,8 @@ } blink::WebWidget* RenderWidget::GetWebWidget() const { - if (owner_delegate_) { - blink::WebWidget* delegate_widget = - owner_delegate_->GetWebWidgetForWidget(); + if (delegate()) { + blink::WebWidget* delegate_widget = delegate()->GetWebWidgetForWidget(); if (delegate_widget) return delegate_widget; } @@ -3212,7 +3214,7 @@ // Only the main frame pulls page scale information from the layer tree host. // Pages scale is shared with non-mainframe widgets via the IPC for // OnSynchronizeVisualProperties. - if (!owner_delegate_) + if (!delegate()) return; page_scale_factor_from_mainframe_ = page_scale_factor;
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 9466b02..e5376e6 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -43,6 +43,7 @@ #include "content/renderer/input/render_widget_input_handler.h" #include "content/renderer/input/render_widget_input_handler_delegate.h" #include "content/renderer/mouse_lock_dispatcher.h" +#include "content/renderer/render_widget_delegate.h" #include "content/renderer/render_widget_mouse_lock_dispatcher.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_message.h" @@ -111,7 +112,7 @@ class RenderFrameImpl; class RenderFrameProxy; class RenderViewImpl; -class RenderWidgetOwnerDelegate; +class RenderWidgetDelegate; class RenderWidgetScreenMetricsEmulator; class ResizingModeSelector; class TextInputClientObserver; @@ -183,11 +184,17 @@ // making it self-referencing, which can be released by calling Close(). void InitForChildLocalRoot(blink::WebFrameWidget* web_frame_widget); - void set_owner_delegate(RenderWidgetOwnerDelegate* owner_delegate) { - DCHECK(!owner_delegate_); - owner_delegate_ = owner_delegate; + // Sets a delegate to handle certain RenderWidget operations that need an + // escape to the RenderView. Also take ownership until RenderWidget lifetime + // has been reassociated with the RenderFrame. This is only set on Widgets + // that are associated with the RenderView. + // TODO(ajwong): Do not have RenderWidget own the delegate. + void set_delegate(std::unique_ptr<RenderWidgetDelegate> delegate) { + DCHECK(!delegate_); + delegate_ = std::move(delegate); } - RenderWidgetOwnerDelegate* owner_delegate() const { return owner_delegate_; } + + RenderWidgetDelegate* delegate() const { return delegate_.get(); } // Returns the RenderWidget for the given routing ID. static RenderWidget* FromRoutingID(int32_t routing_id); @@ -549,18 +556,22 @@ const gfx::Size& max_size); void DisableAutoResizeForTesting(const gfx::Size& new_size); - base::WeakPtr<RenderWidget> AsWeakPtr(); + // Update the WebView's device scale factor. + // TODO(ajwong): This should be moved into RenderView. + void UpdateWebViewWithDeviceScaleFactor(); - protected: - ~RenderWidget() override; + // RenderWidget IPC message handler that can be overridden by subclasses. + virtual void OnSynchronizeVisualProperties(const VisualProperties& params); // Called by Create() functions and subclasses to finish initialization. // |show_callback| will be invoked once WebWidgetClient::Show() occurs, and // should be null if Show() won't be triggered for this widget. void Init(ShowCallback show_callback, blink::WebWidget* web_widget); - // Update the web view's device scale factor. - void UpdateWebViewWithDeviceScaleFactor(); + base::WeakPtr<RenderWidget> AsWeakPtr(); + + protected: + ~RenderWidget() override; // Close the underlying WebWidget and stop the compositor. virtual void Close(); @@ -568,9 +579,6 @@ // Notify subclasses that we initiated the paint operation. virtual void DidInitiatePaint() {} - // RenderWidget IPC message handler that can be overridden by subclasses. - virtual void OnSynchronizeVisualProperties(const VisualProperties& params); - private: // Friend RefCounted so that the dtor can be non-public. Using this class // without ref-counting is an error. @@ -585,7 +593,7 @@ friend class PopupRenderWidget; friend class QueueMessageSwapPromiseTest; friend class RenderWidgetTest; - friend class RenderViewImplTest; + friend class RenderViewImplTest; // TODO(ajwong): Can this be removed? FRIEND_TEST_ALL_PREFIXES(RenderWidgetPopupUnittest, EmulatingPopupRect); static scoped_refptr<base::SingleThreadTaskRunner> GetCleanupTaskRunner(); @@ -611,9 +619,7 @@ void CloseWebWidget(); #if BUILDFLAG(USE_EXTERNAL_POPUP_MENU) - void SetExternalPopupOriginAdjustmentsForEmulation( - ExternalPopupMenu* popup, - RenderWidgetScreenMetricsEmulator* emulator); + void SetExternalPopupOriginAdjustmentsForEmulation(ExternalPopupMenu* popup); #endif // RenderWidget IPC message handlers. @@ -780,10 +786,8 @@ // Whether this widget is for a frame. This excludes widgets that are not for // a frame (eg popups, pepper), but includes both the main frame - // (via owner_delegate_) and subframes (via for_child_local_root_frame_). - bool for_frame() const { - return owner_delegate_ || for_child_local_root_frame_; - } + // (via delegate_) and subframes (via for_child_local_root_frame_). + bool for_frame() const { return delegate_ || for_child_local_root_frame_; } // Routing ID that allows us to communicate to the parent browser process // RenderWidgetHost. @@ -798,8 +802,8 @@ // May be NULL when the window is closing. blink::WebWidget* webwidget_internal_; - // The delegate of the owner of this object. - RenderWidgetOwnerDelegate* owner_delegate_; + // The delegate for this object which is just a RenderViewImpl. + std::unique_ptr<RenderWidgetDelegate> delegate_; // This is lazily constructed and must not outlive webwidget_. std::unique_ptr<LayerTreeView> layer_tree_view_;
diff --git a/content/renderer/render_widget_owner_delegate.h b/content/renderer/render_widget_delegate.h similarity index 92% rename from content/renderer/render_widget_owner_delegate.h rename to content/renderer/render_widget_delegate.h index 1b4cfd2..625e232 100644 --- a/content/renderer/render_widget_owner_delegate.h +++ b/content/renderer/render_widget_delegate.h
@@ -2,25 +2,29 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_RENDERER_RENDER_WIDGET_OWNER_DELEGATE_H_ -#define CONTENT_RENDERER_RENDER_WIDGET_OWNER_DELEGATE_H_ +#ifndef CONTENT_RENDERER_RENDER_WIDGET_DELEGATE_H_ +#define CONTENT_RENDERER_RENDER_WIDGET_DELEGATE_H_ #include "content/common/content_export.h" namespace blink { class WebMouseEvent; -} +class WebWidget; +class WebWidgetClient; +} // namespace blink namespace content { // -// RenderWidgetOwnerDelegate +// RenderWidgetDelegate // // An interface implemented by an object owning a RenderWidget. This is // intended to be temporary until the RenderViewImpl and RenderWidget classes // are disentangled; see https://crbug.com/583347 and https://crbug.com/478281. -class CONTENT_EXPORT RenderWidgetOwnerDelegate { +class CONTENT_EXPORT RenderWidgetDelegate { public: + virtual ~RenderWidgetDelegate() = default; + // Returns the WebWidget if the delegate has one. Otherwise it returns null, // and RenderWidget will fall back to its own WebWidget. virtual blink::WebWidget* GetWebWidgetForWidget() const = 0; @@ -106,11 +110,8 @@ virtual void SetScreenMetricsEmulationParametersForWidget( bool enabled, const blink::WebDeviceEmulationParams& params) = 0; - - protected: - virtual ~RenderWidgetOwnerDelegate() {} }; } // namespace content -#endif // CONTENT_RENDERER_RENDER_WIDGET_OWNER_DELEGATE_H_ +#endif // CONTENT_RENDERER_RENDER_WIDGET_DELEGATE_H_
diff --git a/content/renderer/render_widget_unittest.cc b/content/renderer/render_widget_unittest.cc index 06de14d..a67610e 100644 --- a/content/renderer/render_widget_unittest.cc +++ b/content/renderer/render_widget_unittest.cc
@@ -27,7 +27,7 @@ #include "content/renderer/compositor/layer_tree_view.h" #include "content/renderer/devtools/render_widget_screen_metrics_emulator.h" #include "content/renderer/input/widget_input_handler_manager.h" -#include "content/renderer/render_widget_owner_delegate.h" +#include "content/renderer/render_widget_delegate.h" #include "content/test/fake_compositor_dependencies.h" #include "content/test/mock_render_process.h" #include "ipc/ipc_test_sink.h" @@ -497,7 +497,7 @@ DISALLOW_COPY_AND_ASSIGN(RenderWidgetPopupUnittest); }; -class StubRenderWidgetOwnerDelegate : public RenderWidgetOwnerDelegate { +class StubRenderWidgetDelegate : public RenderWidgetDelegate { public: blink::WebWidget* GetWebWidgetForWidget() const override { return nullptr; } blink::WebWidgetClient* GetWebWidgetClientForWidget() override { @@ -562,9 +562,8 @@ new PopupRenderWidget(&compositor_deps_)); parent_widget->Release(); // Balance Init(). - // Emulation only happens for RenderWidgets with an owner delegate. - StubRenderWidgetOwnerDelegate delegate; - parent_widget->set_owner_delegate(&delegate); + // Emulation only happens for RenderWidgets with a delegate. + parent_widget->set_delegate(std::make_unique<StubRenderWidgetDelegate>()); // Setup emulation on the |parent_widget|. parent_widget->OnSynchronizeVisualProperties(visual_properties);
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc index 23f4ddd..b57903b 100644 --- a/content/renderer/service_worker/service_worker_context_client.cc +++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -20,7 +20,6 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" -#include "content/common/service_worker/service_worker.mojom.h" #include "content/common/service_worker/service_worker_utils.h" #include "content/public/common/content_features.h" #include "content/public/common/network_service_util.h" @@ -59,6 +58,7 @@ #include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom.h" #include "third_party/blink/public/mojom/blob/blob.mojom.h" #include "third_party/blink/public/mojom/blob/blob_registry.mojom.h" +#include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h" @@ -341,7 +341,7 @@ DCHECK(thread_checker.CalledOnValidThread()); } - mojo::Binding<mojom::ServiceWorker> service_worker_binding; + mojo::Binding<blink::mojom::ServiceWorker> service_worker_binding; // Maps for inflight event callbacks. // These are mapped from an event id issued from ServiceWorkerTimeoutTimer to @@ -563,7 +563,7 @@ const GURL& script_url, bool is_starting_installed_worker, RendererPreferences renderer_preferences, - mojom::ServiceWorkerRequest service_worker_request, + blink::mojom::ServiceWorkerRequest service_worker_request, blink::mojom::ControllerServiceWorkerRequest controller_request, mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host, mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info, @@ -1515,7 +1515,7 @@ } void ServiceWorkerContextClient::DispatchExtendableMessageEvent( - mojom::ExtendableMessageEventPtr event, + blink::mojom::ExtendableMessageEventPtr event, DispatchExtendableMessageEventCallback callback) { int request_id = context_->timeout_timer->StartEvent( CreateAbortCallback(&context_->message_event_callbacks)); @@ -1546,7 +1546,7 @@ void ServiceWorkerContextClient:: DispatchExtendableMessageEventWithCustomTimeout( - mojom::ExtendableMessageEventPtr event, + blink::mojom::ExtendableMessageEventPtr event, base::TimeDelta timeout, DispatchExtendableMessageEventCallback callback) { int request_id = context_->timeout_timer->StartEventWithCustomTimeout( @@ -1659,7 +1659,7 @@ DispatchPushEventCallback callback) { int request_id = context_->timeout_timer->StartEventWithCustomTimeout( CreateAbortCallback(&context_->push_event_callbacks), - base::TimeDelta::FromSeconds(mojom::kPushEventTimeoutSeconds)); + base::TimeDelta::FromSeconds(blink::mojom::kPushEventTimeoutSeconds)); context_->push_event_callbacks.emplace(request_id, std::move(callback)); TRACE_EVENT_WITH_FLOW0("ServiceWorker", "ServiceWorkerContextClient::DispatchPushEvent", @@ -1806,6 +1806,14 @@ embedded_worker_client_->StopWorker(); } +int ServiceWorkerContextClient::WillStartTask() { + return context_->timeout_timer->StartEvent(base::DoNothing()); +} + +void ServiceWorkerContextClient::DidEndTask(int task_id) { + context_->timeout_timer->EndEvent(task_id); +} + base::WeakPtr<ServiceWorkerContextClient> ServiceWorkerContextClient::GetWeakPtr() { DCHECK(worker_task_runner_->RunsTasksInCurrentSequence());
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h index 352dc93a..b5d2db9 100644 --- a/content/renderer/service_worker/service_worker_context_client.h +++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -20,7 +20,6 @@ #include "base/strings/string16.h" #include "base/time/time.h" #include "content/common/service_worker/embedded_worker.mojom.h" -#include "content/common/service_worker/service_worker.mojom.h" #include "content/common/service_worker/service_worker_provider.mojom.h" #include "content/common/service_worker/service_worker_types.h" #include "ipc/ipc_listener.h" @@ -70,7 +69,7 @@ // called on the worker thread. class CONTENT_EXPORT ServiceWorkerContextClient : public blink::WebServiceWorkerContextClient, - public mojom::ServiceWorker { + public blink::mojom::ServiceWorker { public: // Returns a thread-specific client instance. This does NOT create a // new instance. @@ -90,7 +89,7 @@ const GURL& script_url, bool is_starting_installed_worker, RendererPreferences renderer_preferences, - mojom::ServiceWorkerRequest service_worker_request, + blink::mojom::ServiceWorkerRequest service_worker_request, blink::mojom::ControllerServiceWorkerRequest controller_request, mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host, mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info, @@ -196,6 +195,8 @@ CreateServiceWorkerNetworkProvider() override; scoped_refptr<blink::WebWorkerFetchContext> CreateServiceWorkerFetchContext( blink::WebServiceWorkerNetworkProvider*) override; + int WillStartTask() override; + void DidEndTask(int task_id) override; // Dispatches the fetch event if the worker is running normally, and queues it // instead if the worker has already requested to be terminated by the @@ -223,6 +224,7 @@ DispatchOrQueueFetchEvent_RequestedTerminationAndWakeUp); FRIEND_TEST_ALL_PREFIXES(ServiceWorkerContextClientTest, DispatchOrQueueFetchEvent_NotRequestedTermination); + FRIEND_TEST_ALL_PREFIXES(ServiceWorkerContextClientTest, TaskInServiceWorker); // Get routing_id for sending message to the ServiceWorkerVersion // in the browser process. @@ -230,7 +232,7 @@ void SendWorkerStarted(blink::mojom::ServiceWorkerStartStatus status); - // Implements mojom::ServiceWorker. + // Implements blink::mojom::ServiceWorker. void InitializeGlobalScope( blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host, blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info) @@ -251,10 +253,10 @@ blink::mojom::BackgroundFetchRegistrationPtr registration, DispatchBackgroundFetchSuccessEventCallback callback) override; void DispatchExtendableMessageEvent( - mojom::ExtendableMessageEventPtr event, + blink::mojom::ExtendableMessageEventPtr event, DispatchExtendableMessageEventCallback callback) override; void DispatchExtendableMessageEventWithCustomTimeout( - mojom::ExtendableMessageEventPtr event, + blink::mojom::ExtendableMessageEventPtr event, base::TimeDelta timeout, DispatchExtendableMessageEventCallback callback) override; void DispatchFetchEvent( @@ -377,7 +379,7 @@ blink::WebServiceWorkerContextProxy* proxy_; // These Mojo objects are bound on the worker thread. - mojom::ServiceWorkerRequest pending_service_worker_request_; + blink::mojom::ServiceWorkerRequest pending_service_worker_request_; blink::mojom::ControllerServiceWorkerRequest pending_controller_request_; // This is bound on the main thread.
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 b416c78..fb3c34c2 100644 --- a/content/renderer/service_worker/service_worker_context_client_unittest.cc +++ b/content/renderer/service_worker/service_worker_context_client_unittest.cc
@@ -50,7 +50,7 @@ // Pipes connected to the context client. struct ContextClientPipes { // From the browser to ServiceWorkerContextClient. - mojom::ServiceWorkerPtr service_worker; + blink::mojom::ServiceWorkerPtr service_worker; blink::mojom::ControllerServiceWorkerPtr controller; blink::mojom::ServiceWorkerRegistrationObjectAssociatedPtr registration; @@ -306,6 +306,30 @@ return context_client; } + std::unique_ptr<ServiceWorkerContextClient> CreateIdleContextClient( + ContextClientPipes* pipes, + MockWebServiceWorkerContextProxy* mock_proxy) { + std::unique_ptr<ServiceWorkerContextClient> context_client = + CreateContextClient(pipes, mock_proxy); + context_client->DidEvaluateScript(true /* success */); + task_runner()->RunUntilIdle(); + EXPECT_TRUE(mock_proxy->fetch_events().empty()); + is_idle_ = false; + auto timer = std::make_unique<ServiceWorkerTimeoutTimer>( + CreateCallbackWithCalledFlag(&is_idle_), + task_runner()->GetMockTickClock()); + context_client->SetTimeoutTimerForTesting(std::move(timer)); + + // Ensure the idle state. + EXPECT_FALSE(context_client->RequestedTermination()); + task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kIdleDelay + + ServiceWorkerTimeoutTimer::kUpdateInterval + + base::TimeDelta::FromSeconds(1)); + EXPECT_TRUE(context_client->RequestedTermination()); + + return context_client; + } + scoped_refptr<base::TestMockTimeTaskRunner> task_runner() const { return task_runner_; } @@ -314,6 +338,7 @@ base::MessageLoop message_loop_; scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; base::test::ScopedFeatureList feature_list_; + bool is_idle_; }; TEST_F(ServiceWorkerContextClientTest, Ping) { @@ -447,23 +472,7 @@ ContextClientPipes pipes; MockWebServiceWorkerContextProxy mock_proxy; std::unique_ptr<ServiceWorkerContextClient> context_client = - CreateContextClient(&pipes, &mock_proxy); - context_client->DidEvaluateScript(true /* success */); - task_runner()->RunUntilIdle(); - EXPECT_TRUE(mock_proxy.fetch_events().empty()); - - bool is_idle = false; - auto timer = std::make_unique<ServiceWorkerTimeoutTimer>( - CreateCallbackWithCalledFlag(&is_idle), - task_runner()->GetMockTickClock()); - context_client->SetTimeoutTimerForTesting(std::move(timer)); - - // Ensure the idle state. - EXPECT_FALSE(context_client->RequestedTermination()); - task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kIdleDelay + - ServiceWorkerTimeoutTimer::kUpdateInterval + - base::TimeDelta::FromSeconds(1)); - EXPECT_TRUE(context_client->RequestedTermination()); + CreateIdleContextClient(&pipes, &mock_proxy); const GURL expected_url("https://example.com/expected"); @@ -494,22 +503,7 @@ ContextClientPipes pipes; MockWebServiceWorkerContextProxy mock_proxy; std::unique_ptr<ServiceWorkerContextClient> context_client = - CreateContextClient(&pipes, &mock_proxy); - context_client->DidEvaluateScript(true /* success */); - task_runner()->RunUntilIdle(); - EXPECT_TRUE(mock_proxy.fetch_events().empty()); - bool is_idle = false; - auto timer = std::make_unique<ServiceWorkerTimeoutTimer>( - CreateCallbackWithCalledFlag(&is_idle), - task_runner()->GetMockTickClock()); - context_client->SetTimeoutTimerForTesting(std::move(timer)); - - // Ensure the idle state. - EXPECT_FALSE(context_client->RequestedTermination()); - task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kIdleDelay + - ServiceWorkerTimeoutTimer::kUpdateInterval + - base::TimeDelta::FromSeconds(1)); - EXPECT_TRUE(context_client->RequestedTermination()); + CreateIdleContextClient(&pipes, &mock_proxy); const GURL expected_url_1("https://example.com/expected_1"); const GURL expected_url_2("https://example.com/expected_2"); @@ -534,7 +528,7 @@ } EXPECT_TRUE(mock_proxy.fetch_events().empty()); - // Another event dispatched to mojom::ServiceWorker wakes up + // Another event dispatched to blink::mojom::ServiceWorker wakes up // the context client. { blink::mojom::ServiceWorkerFetchResponseCallbackPtr fetch_callback_ptr; @@ -558,4 +552,23 @@ static_cast<GURL>(mock_proxy.fetch_events()[1].second.Url())); } +TEST_F(ServiceWorkerContextClientTest, TaskInServiceWorker) { + EnableServicification(); + ContextClientPipes pipes; + MockWebServiceWorkerContextProxy mock_proxy; + std::unique_ptr<ServiceWorkerContextClient> context_client = + CreateIdleContextClient(&pipes, &mock_proxy); + + int task_id = context_client->WillStartTask(); + EXPECT_FALSE(context_client->RequestedTermination()); + context_client->DidEndTask(task_id); + EXPECT_FALSE(context_client->RequestedTermination()); + + // Ensure the idle state. + task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kIdleDelay + + ServiceWorkerTimeoutTimer::kUpdateInterval + + base::TimeDelta::FromSeconds(1)); + EXPECT_TRUE(context_client->RequestedTermination()); +} + } // namespace content
diff --git a/content/renderer/service_worker/service_worker_type_converters.h b/content/renderer/service_worker/service_worker_type_converters.h index d4ce8af..aedfaea 100644 --- a/content/renderer/service_worker/service_worker_type_converters.h +++ b/content/renderer/service_worker/service_worker_type_converters.h
@@ -5,7 +5,6 @@ #ifndef CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_TYPE_CONVERTERS_H_ #define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_TYPE_CONVERTERS_H_ -#include "content/common/service_worker/service_worker.mojom.h" #include "third_party/blink/public/common/service_worker/service_worker_status_code.h" #include "third_party/blink/public/mojom/payments/payment_app.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
diff --git a/content/renderer/webgraphicscontext3d_provider_impl.cc b/content/renderer/webgraphicscontext3d_provider_impl.cc index b828238..a26f1a5 100644 --- a/content/renderer/webgraphicscontext3d_provider_impl.cc +++ b/content/renderer/webgraphicscontext3d_provider_impl.cc
@@ -104,9 +104,4 @@ return cache_iterator->second.get(); } -gpu::SharedImageInterface* -WebGraphicsContext3DProviderImpl::SharedImageInterface() { - return provider_->SharedImageInterface(); -} - } // namespace content
diff --git a/content/renderer/webgraphicscontext3d_provider_impl.h b/content/renderer/webgraphicscontext3d_provider_impl.h index 354b166..88b0f7ba 100644 --- a/content/renderer/webgraphicscontext3d_provider_impl.h +++ b/content/renderer/webgraphicscontext3d_provider_impl.h
@@ -54,7 +54,6 @@ cc::ImageDecodeCache* ImageDecodeCache( SkColorType color_type, sk_sp<SkColorSpace> color_space) override; - gpu::SharedImageInterface* SharedImageInterface() override; ws::ContextProviderCommandBuffer* context_provider() const { return provider_.get();
diff --git a/content/shell/renderer/shell_content_renderer_client.cc b/content/shell/renderer/shell_content_renderer_client.cc index 5a50a0ec..deab3f9 100644 --- a/content/shell/renderer/shell_content_renderer_client.cc +++ b/content/shell/renderer/shell_content_renderer_client.cc
@@ -135,8 +135,9 @@ void ShellContentRendererClient::PrepareErrorPage( RenderFrame* render_frame, - const blink::WebURLRequest& failed_request, const blink::WebURLError& error, + const std::string& http_method, + bool ignoring_cache, std::string* error_html) { if (error_html && error_html->empty()) { *error_html = @@ -151,8 +152,9 @@ void ShellContentRendererClient::PrepareErrorPageForHttpStatusError( content::RenderFrame* render_frame, - const blink::WebURLRequest& failed_request, const GURL& unreachable_url, + const std::string& http_method, + bool ignoring_cache, int http_status, std::string* error_html) { if (error_html) {
diff --git a/content/shell/renderer/shell_content_renderer_client.h b/content/shell/renderer/shell_content_renderer_client.h index b4a9408f5..5a30271 100644 --- a/content/shell/renderer/shell_content_renderer_client.h +++ b/content/shell/renderer/shell_content_renderer_client.h
@@ -29,15 +29,16 @@ void RenderViewCreated(RenderView* render_view) override; bool HasErrorPage(int http_status_code) override; void PrepareErrorPage(RenderFrame* render_frame, - const blink::WebURLRequest& failed_request, const blink::WebURLError& error, + const std::string& http_method, + bool ignoring_cache, std::string* error_html) override; - void PrepareErrorPageForHttpStatusError( - content::RenderFrame* render_frame, - const blink::WebURLRequest& failed_request, - const GURL& unreachable_url, - int http_status, - std::string* error_html) override; + void PrepareErrorPageForHttpStatusError(content::RenderFrame* render_frame, + const GURL& unreachable_url, + const std::string& http_method, + bool ignoring_cache, + int http_status, + std::string* error_html) override; // TODO(mkwst): These toggle based on the kEnablePepperTesting flag. Do we // need that outside of web tests?
diff --git a/content/test/data/accessibility/aria/aria-rowtext-expected-win.txt b/content/test/data/accessibility/aria/aria-rowtext-expected-win.txt index 93c495f7..35e33ee 100644 --- a/content/test/data/accessibility/aria/aria-rowtext-expected-win.txt +++ b/content/test/data/accessibility/aria/aria-rowtext-expected-win.txt
@@ -1,12 +1,12 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ++ROLE_SYSTEM_TABLE ++++ROLE_SYSTEM_ROW -++++++ROLE_SYSTEM_CELL name='cell A3' rowindex:3 rowtext:3 coltext:A +++++++ROLE_SYSTEM_CELL name='cell A3' colindex:1 rowindex:3 rowtext:3 coltext:A ++++++++ROLE_SYSTEM_STATICTEXT name='cell A3' -++++++ROLE_SYSTEM_CELL name='cell B3' rowindex:3 rowtext:3 coltext:B +++++++ROLE_SYSTEM_CELL name='cell B3' colindex:2 rowindex:3 rowtext:3 coltext:B ++++++++ROLE_SYSTEM_STATICTEXT name='cell B3' ++++ROLE_SYSTEM_ROW -++++++ROLE_SYSTEM_CELL name='cell A4' rowindex:4 rowtext:4 coltext:A +++++++ROLE_SYSTEM_CELL name='cell A4' colindex:1 rowindex:4 rowtext:4 coltext:A ++++++++ROLE_SYSTEM_STATICTEXT name='cell A4' -++++++ROLE_SYSTEM_CELL name='cell B4' rowindex:4 rowtext:4 coltext:B +++++++ROLE_SYSTEM_CELL name='cell B4' colindex:2 rowindex:4 rowtext:4 coltext:B ++++++++ROLE_SYSTEM_STATICTEXT name='cell B4'
diff --git a/content/test/data/accessibility/aria/table-column-hidden-expected-win.txt b/content/test/data/accessibility/aria/table-column-hidden-expected-win.txt index 5422379..6887c8a6 100644 --- a/content/test/data/accessibility/aria/table-column-hidden-expected-win.txt +++ b/content/test/data/accessibility/aria/table-column-hidden-expected-win.txt
@@ -1,5 +1,5 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE -++ROLE_SYSTEM_TABLE colcount:4 +++ROLE_SYSTEM_TABLE colcount:4 rowcount:3 ++++ROLE_SYSTEM_ROW ++++++ROLE_SYSTEM_COLUMNHEADER name='Month' colindex:1 rowindex:1 ++++++++ROLE_SYSTEM_STATICTEXT name='Month' @@ -15,11 +15,11 @@ ++++++ROLE_SYSTEM_CELL name='Sunny' FOCUSABLE colindex:4 rowindex:2 ++++++++ROLE_SYSTEM_STATICTEXT name='Sunny' ++++ROLE_SYSTEM_ROW -++++++ROLE_SYSTEM_CELL name='January' FOCUSABLE colindex:1 rowindex:2 +++++++ROLE_SYSTEM_CELL name='January' FOCUSABLE colindex:1 rowindex:3 ++++++++ROLE_SYSTEM_STATICTEXT name='January' -++++++ROLE_SYSTEM_CELL name='02' FOCUSABLE colindex:2 rowindex:2 +++++++ROLE_SYSTEM_CELL name='02' FOCUSABLE colindex:2 rowindex:3 ++++++++ROLE_SYSTEM_STATICTEXT name='02' -++++++ROLE_SYSTEM_CELL name='Rainy' FOCUSABLE colindex:4 rowindex:2 +++++++ROLE_SYSTEM_CELL name='Rainy' FOCUSABLE colindex:4 rowindex:3 ++++++++ROLE_SYSTEM_STATICTEXT name='Rainy' ++IA2_ROLE_PARAGRAPH ++++ROLE_SYSTEM_STATICTEXT name='done'
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py index 34d4ca9..e57909a2 100644 --- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -82,12 +82,6 @@ # All platforms. self.Fail('conformance2/glsl3/tricky-loop-conditions.html', bug=905001) - # Newly introduced flaky failure. - # TODO(kbr): re-enable after fixing test. - self.Flaky('conformance/textures/misc/' + - 'canvas-teximage-after-multiple-drawimages.html', - bug=905682) - # This test needs to be rewritten to measure its expected # performance; it's currently too flaky even on release bots. self.Skip('conformance/rendering/texture-switch-performance.html', @@ -316,11 +310,6 @@ self.Fail('conformance/misc/webgl-specific-stencil-settings.html', ['passthrough'], bug=844349) - # TODO(jmadill): Re-enable after fix. http://anglebug.com/3012 - self.Fail('conformance2/extensions/' + - 'webgl_multiview_transform_feedback.html', - ['passthrough'], bug=3012) # ANGLE bug ID - # Passthrough command decoder / OpenGL self.Fail('conformance2/misc/uninitialized-test-2.html', ['passthrough', 'opengl'], bug=602688)
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py index 45cc9eeb4..321b83c 100644 --- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -126,12 +126,6 @@ 'in-parameter-passed-as-inout-argument-and-global.html', ['nvidia'], bug=792210) - # Newly introduced flaky failure. - # TODO(kbr): re-enable after fixing test. - self.Flaky('conformance/textures/misc/' + - 'canvas-teximage-after-multiple-drawimages.html', - bug=905682) - # This test needs to be rewritten to measure its expected # performance; it's currently too flaky even on release bots. self.Skip('conformance/rendering/texture-switch-performance.html', @@ -207,9 +201,6 @@ ['win', 'nvidia', 'no_passthrough'], bug=626524) self.Flaky('conformance/textures/misc/texture-upload-size.html', ['win', 'nvidia'], bug=630860) - self.Skip('conformance/rendering/out-of-bounds-index-buffers.html', - ['win', 'nvidia', 'passthrough', 'vulkan'], bug=3018) # ANGLE bug - # self.Fail('conformance/extensions/ext-sRGB.html', # ['win', 'nvidia', 'no_passthrough'], bug=679696) @@ -832,6 +823,9 @@ ['android', ('qualcomm', 'Adreno (TM) 420')], bug=899754) self.Fail('conformance/rendering/clear-after-copyTexImage2D.html', ['android', ('qualcomm', 'Adreno (TM) 420')], bug=737002) + self.Fail('conformance/rendering/' + + 'color-mask-preserved-during-implicit-clears.html', + ['android', ('qualcomm', 'Adreno (TM) 420')], bug=911918) self.Fail('conformance/rendering/gl-scissor-test.html', ['android', ('qualcomm', 'Adreno (TM) 420')], bug=499555) self.Fail('conformance/rendering/gl-viewport-test.html',
diff --git a/content/test/web_test_support.cc b/content/test/web_test_support.cc index 3e36ec7..d01f12f 100644 --- a/content/test/web_test_support.cc +++ b/content/test/web_test_support.cc
@@ -208,7 +208,7 @@ // RenderWidget WebWidgetTestProxyBase // \\ // // WebWidgetTestProxy - RenderWidget* render_widget = local_root_impl->GetRenderWidget(); + RenderWidget* render_widget = local_root_impl->GetLocalRootRenderWidget(); auto* proxy = static_cast<test_runner::WebWidgetTestProxy*>(render_widget); return static_cast<test_runner::WebWidgetTestProxyBase*>(proxy); } @@ -555,7 +555,7 @@ void ForceTextInputStateUpdateForRenderFrame(RenderFrame* frame) { RenderWidget* render_widget = - static_cast<RenderFrameImpl*>(frame)->GetRenderWidget(); + static_cast<RenderFrameImpl*>(frame)->GetLocalRootRenderWidget(); render_widget->ShowVirtualKeyboard(); }
diff --git a/device/bluetooth/bluetooth_adapter.h b/device/bluetooth/bluetooth_adapter.h index c0de6069..07c9182 100644 --- a/device/bluetooth/bluetooth_adapter.h +++ b/device/bluetooth/bluetooth_adapter.h
@@ -122,6 +122,21 @@ BluetoothDevice* device, const std::string& old_address) {} + // Called when advertisement is received. + // + // Override this function to observe LE advertisements. This function + // returns the raw values that have been parsed from EIR. + virtual void DeviceAdvertisementReceived( + const std::string& device_address, + const base::Optional<std::string>& device_name, + const base::Optional<std::string>& advertisement_name, + base::Optional<int8_t> rssi, + base::Optional<int8_t> tx_power, + uint16_t appearance, + const BluetoothDevice::UUIDList& advertised_uuids, + const BluetoothDevice::ServiceDataMap& service_data_map, + const BluetoothDevice::ManufacturerDataMap& manufacturer_data_map) {} + // TODO(crbug.com/732991): Update comment and fix redundant #ifs throughout. #if defined(OS_CHROMEOS) || defined(OS_LINUX) // This function is implemented for ChromeOS only, and the support for
diff --git a/device/bluetooth/bluetooth_adapter_mac.mm b/device/bluetooth/bluetooth_adapter_mac.mm index fafb987..7848d53b 100644 --- a/device/bluetooth/bluetooth_adapter_mac.mm +++ b/device/bluetooth/bluetooth_adapter_mac.mm
@@ -693,10 +693,29 @@ // 0xXX: -127 to +127 dBm" // Core Specification Supplement (CSS) v7, Part 1.5 // https://developer.apple.com/documentation/corebluetooth/cbadvertisementdatatxpowerlevelkey + // TODO(dougt): We shoud treat |tx_power| and |local_name| as optional as + // they do not have to be specified by the device. NSNumber* tx_power = [advertisement_data objectForKey:CBAdvertisementDataTxPowerLevelKey]; int8_t clamped_tx_power = BluetoothDevice::ClampPower([tx_power intValue]); + // Get the Advertising name + NSString* local_name = + [advertisement_data objectForKey:CBAdvertisementDataLocalNameKey]; + + for (auto& observer : observers_) { + base::Optional<std::string> device_name_opt = device_mac->GetName(); + base::Optional<std::string> local_name_opt = + base::SysNSStringToUTF8(local_name); + + observer.DeviceAdvertisementReceived( + device_mac->GetAddress(), device_name_opt, local_name_opt, rssi, + clamped_tx_power, + BluetoothDevice::kAppearanceNotPresent, /* TODO(crbug.com/588083) + Implement appearance */ + advertised_uuids, service_data_map, manufacturer_data_map); + } + device_mac->UpdateAdvertisementData( BluetoothDevice::ClampPower(rssi), base::nullopt /* flags */, std::move(advertised_uuids),
diff --git a/device/bluetooth/bluetooth_device_unittest.cc b/device/bluetooth/bluetooth_device_unittest.cc index 4e1d05c..b681132 100644 --- a/device/bluetooth/bluetooth_device_unittest.cc +++ b/device/bluetooth/bluetooth_device_unittest.cc
@@ -589,6 +589,44 @@ EXPECT_EQ(ToInt8(TestTxPower::LOWEST), device->GetInquiryTxPower().value()); } +#if defined(OS_MACOSX) +// TODO(dougt) As I turn on new platforms for WebBluetooth Scanning, +// I will relax this #ifdef +TEST_F(BluetoothTest, DeviceAdvertisementReceived) { + if (!PlatformSupportsLowEnergy()) { + LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; + return; + } + + InitWithFakeAdapter(); + TestBluetoothAdapterObserver observer(adapter_); + + StartLowEnergyDiscoverySession(); + SimulateLowEnergyDevice(1); + + EXPECT_EQ(1, observer.device_advertisement_raw_received_count()); + EXPECT_EQ(kTestDeviceAddress1, + observer.device_last_device_name().value_or("")); + EXPECT_EQ(kTestDeviceName, + observer.device_last_advertisement_name().value_or("")); + + // TestRSSI::LOWEST + EXPECT_EQ(-81, observer.device_last_rssi().value_or(-1)); + + // TestTxPower::LOWEST + EXPECT_EQ(-40, observer.device_last_tx_power().value_or(-1)); + + // TODO(crbug.com/588083) + // EXPECT_EQ(0x04, observer.device_last_appearance()); + + // TODO(dougt): Service Data, ManufacturerData, Advertised UUID + + // Double check that we can receive another advertisement. + SimulateLowEnergyDevice(2); + EXPECT_EQ(2, observer.device_advertisement_raw_received_count()); +} +#endif + #if defined(OS_ANDROID) || defined(OS_MACOSX) #define MAYBE_GetUUIDs_Connection GetUUIDs_Connection #else
diff --git a/device/bluetooth/test/fake_central.cc b/device/bluetooth/test/fake_central.cc index c1185f0..c030e60 100644 --- a/device/bluetooth/test/fake_central.cc +++ b/device/bluetooth/test/fake_central.cc
@@ -80,16 +80,29 @@ } auto& scan_record = scan_result_ptr->scan_record; + auto uuids = ValueOrDefault(std::move(scan_record->uuids)); + auto service_data = ValueOrDefault(std::move(scan_record->service_data)); + auto manufacturer_data = ToManufacturerDataMap( + ValueOrDefault(std::move(scan_record->manufacturer_data))); + + for (auto& observer : observers_) { + observer.DeviceAdvertisementReceived( + scan_result_ptr->device_address, scan_record->name, scan_record->name, + scan_result_ptr->rssi, scan_record->tx_power->value, + device::BluetoothDevice:: + kAppearanceNotPresent, /* TODO(crbug.com/588083) + Implement appearance + */ + uuids, service_data, manufacturer_data); + } + fake_peripheral->SetName(std::move(scan_record->name)); fake_peripheral->UpdateAdvertisementData( - scan_result_ptr->rssi, base::nullopt /* flags */, - ValueOrDefault(std::move(scan_record->uuids)), + scan_result_ptr->rssi, base::nullopt /* flags */, uuids, scan_record->tx_power->has_value ? base::make_optional(scan_record->tx_power->value) : base::nullopt, - ValueOrDefault(std::move(scan_record->service_data)), - ToManufacturerDataMap( - ValueOrDefault(std::move(scan_record->manufacturer_data)))); + service_data, manufacturer_data); if (is_new_device) { // Call DeviceAdded on observers because it is a newly detected peripheral.
diff --git a/device/bluetooth/test/test_bluetooth_adapter_observer.cc b/device/bluetooth/test/test_bluetooth_adapter_observer.cc index 1c1ce682..eccdf250 100644 --- a/device/bluetooth/test/test_bluetooth_adapter_observer.cc +++ b/device/bluetooth/test/test_bluetooth_adapter_observer.cc
@@ -37,6 +37,12 @@ device_added_count_ = 0; device_changed_count_ = 0; device_address_changed_count_ = 0; + device_advertisement_raw_received_count_ = 0; + last_device_name_ = ""; + last_advertisement_name_ = ""; + last_rssi_ = 128; + last_tx_power_ = 128; + last_appearance_ = 128; #if defined(OS_CHROMEOS) || defined(OS_LINUX) device_paired_changed_count_ = 0; device_new_paired_status_ = false; @@ -139,6 +145,27 @@ QuitMessageLoop(); } +void TestBluetoothAdapterObserver::DeviceAdvertisementReceived( + const std::string& device_address, + const base::Optional<std::string>& device_name, + const base::Optional<std::string>& advertisement_name, + base::Optional<int8_t> rssi, + base::Optional<int8_t> tx_power, + uint16_t appearance, + const device::BluetoothDevice::UUIDList& advertised_uuids, + const device::BluetoothDevice::ServiceDataMap& service_data_map, + const device::BluetoothDevice::ManufacturerDataMap& manufacturer_data_map) { + ++device_advertisement_raw_received_count_; + last_device_name_ = device_address; + last_advertisement_name_ = device_name; + last_rssi_ = rssi; + last_tx_power_ = tx_power; + last_appearance_ = appearance; + // TODO(dougt): Test advertised_uuids, service_data_map, manufacturer_data_map + + QuitMessageLoop(); +} + #if defined(OS_CHROMEOS) || defined(OS_LINUX) void TestBluetoothAdapterObserver::DevicePairedChanged( device::BluetoothAdapter* adapter,
diff --git a/device/bluetooth/test/test_bluetooth_adapter_observer.h b/device/bluetooth/test/test_bluetooth_adapter_observer.h index 3a05d75b..afe04f54 100644 --- a/device/bluetooth/test/test_bluetooth_adapter_observer.h +++ b/device/bluetooth/test/test_bluetooth_adapter_observer.h
@@ -38,6 +38,17 @@ void DeviceAddressChanged(device::BluetoothAdapter* adapter, device::BluetoothDevice* device, const std::string& old_address) override; + void DeviceAdvertisementReceived( + const std::string& device_id, + const base::Optional<std::string>& device_name, + const base::Optional<std::string>& advertisement_name, + base::Optional<int8_t> rssi, + base::Optional<int8_t> tx_power, + uint16_t appearance, + const device::BluetoothDevice::UUIDList& advertised_uuids, + const device::BluetoothDevice::ServiceDataMap& service_data_map, + const device::BluetoothDevice::ManufacturerDataMap& manufacturer_data_map) + override; #if defined(OS_CHROMEOS) || defined(OS_LINUX) void DevicePairedChanged(device::BluetoothAdapter* adapter, device::BluetoothDevice* device, @@ -102,6 +113,21 @@ int device_address_changed_count() const { return device_address_changed_count_; } + + // Advertisement related: + int device_advertisement_raw_received_count() const { + return device_advertisement_raw_received_count_; + } + const base::Optional<std::string>& device_last_device_name() const { + return last_device_name_; + } + const base::Optional<std::string>& device_last_advertisement_name() const { + return last_advertisement_name_; + } + base::Optional<int8_t> device_last_rssi() const { return last_rssi_; } + base::Optional<int8_t> device_last_tx_power() const { return last_tx_power_; } + uint16_t device_last_appearance() const { return last_appearance_; } + #if defined(OS_CHROMEOS) || defined(OS_LINUX) int device_paired_changed_count() const { return device_paired_changed_count_; @@ -196,6 +222,15 @@ int device_added_count_; int device_changed_count_; int device_address_changed_count_; + + // Advertisement related + int device_advertisement_raw_received_count_; + base::Optional<std::string> last_device_name_; + base::Optional<std::string> last_advertisement_name_; + base::Optional<int8_t> last_rssi_; + base::Optional<int8_t> last_tx_power_; + uint16_t last_appearance_; + #if defined(OS_CHROMEOS) || defined(OS_LINUX) int device_paired_changed_count_; bool device_new_paired_status_;
diff --git a/docs/accessibility/chromevox_on_desktop_linux.md b/docs/accessibility/chromevox_on_desktop_linux.md index b657f98b..aea0c93 100644 --- a/docs/accessibility/chromevox_on_desktop_linux.md +++ b/docs/accessibility/chromevox_on_desktop_linux.md
@@ -110,6 +110,19 @@ After you do that, just run "chrome" as above (e.g. out/cros/chrome) and press Ctrl+Alt+Z, and you should hear it speak! If not, check the logs. +### eSpeak + +To get [eSpeak](espeak.md) on Chrome OS on Desktop Linux, copy the eSpeak +extension (chrome branch) to the same place: + +``` +cd ~ +git clone https://chromium.googlesource.com/chromiumos/third_party/espeak-ng +cd espeak-ng +git checkout chrome +sudo cp -r chrome-extension /usr/share/chromeos-assets/speech_synthesis/espeak-ng +``` + ## Braille ChromeVox uses extension APIs to deliver braille to Brltty through libbrlapi
diff --git a/docs/accessibility/espeak.md b/docs/accessibility/espeak.md index d06123e..38e539ed 100644 --- a/docs/accessibility/espeak.md +++ b/docs/accessibility/espeak.md
@@ -127,3 +127,8 @@ in this package, then commit the change to git, ensuring that you're changing both the ebuild and manifest file and adding appropriate BUG= and TEST= lines, then use 'repo upload' to upload the change for review. + +## Running on Chrome OS on Desktop Linux + +See [Chromevox on Desktop Linux](chromevox_on_desktop_linux.md#speech) for more +how to use eSpeak's speech engine on Chrome OS emulated on desktop Linux. \ No newline at end of file
diff --git a/extensions/browser/api/file_handlers/mime_util.cc b/extensions/browser/api/file_handlers/mime_util.cc index 8a92327..19912bca 100644 --- a/extensions/browser/api/file_handlers/mime_util.cc +++ b/extensions/browser/api/file_handlers/mime_util.cc
@@ -140,7 +140,7 @@ #if defined(OS_CHROMEOS) NonNativeFileSystemDelegate* delegate = ExtensionsAPIClient::Get()->GetNonNativeFileSystemDelegate(); - if (delegate && delegate->IsUnderNonNativeLocalPath(context, local_path)) { + if (delegate && delegate->HasNonNativeMimeTypeProvider(context, local_path)) { // For non-native files, try to get the MIME type from metadata. If not // available, then try to guess from the extension. Never sniff (because // it can be very slow).
diff --git a/extensions/browser/api/file_handlers/non_native_file_system_delegate.h b/extensions/browser/api/file_handlers/non_native_file_system_delegate.h index c8867f2c..f430b849 100644 --- a/extensions/browser/api/file_handlers/non_native_file_system_delegate.h +++ b/extensions/browser/api/file_handlers/non_native_file_system_delegate.h
@@ -28,6 +28,11 @@ virtual bool IsUnderNonNativeLocalPath(content::BrowserContext* context, const base::FilePath& path) = 0; + // Checks whether |path| points to a filesystem that requires special handling + // for retrieving mime types. + virtual bool HasNonNativeMimeTypeProvider(content::BrowserContext* context, + const base::FilePath& path) = 0; + // Returns the mime type of the file pointed by |path|, and asynchronously // sends the result to |callback|. virtual void GetNonNativeLocalPathMimeType(
diff --git a/extensions/renderer/extension_frame_helper.cc b/extensions/renderer/extension_frame_helper.cc index cd591a86..8302c6ce 100644 --- a/extensions/renderer/extension_frame_helper.cc +++ b/extensions/renderer/extension_frame_helper.cc
@@ -326,8 +326,8 @@ // be resumed when it happens. It doesn't apply to sandboxed pages. if (view_type_ == VIEW_TYPE_APP_WINDOW && render_frame()->IsMainFrame() && !has_started_first_navigation_ && - GURL(document_loader->GetRequest().Url()).SchemeIs(kExtensionScheme) && - !ScriptContext::IsSandboxedPage(document_loader->GetRequest().Url())) { + GURL(document_loader->GetUrl()).SchemeIs(kExtensionScheme) && + !ScriptContext::IsSandboxedPage(document_loader->GetUrl())) { document_loader->BlockParser(); }
diff --git a/extensions/renderer/script_context.cc b/extensions/renderer/script_context.cc index 0d11105..b7a941b 100644 --- a/extensions/renderer/script_context.cc +++ b/extensions/renderer/script_context.cc
@@ -274,7 +274,7 @@ frame->GetProvisionalDocumentLoader() ? frame->GetProvisionalDocumentLoader() : frame->GetDocumentLoader(); - return document_loader ? GURL(document_loader->GetRequest().Url()) : GURL(); + return document_loader ? GURL(document_loader->GetUrl()) : GURL(); } // static @@ -287,9 +287,9 @@ ? frame->GetProvisionalDocumentLoader() : frame->GetDocumentLoader(); if (document_loader && - frame->GetSecurityOrigin().CanAccess(blink::WebSecurityOrigin::Create( - document_loader->GetRequest().Url()))) { - return GURL(document_loader->GetRequest().Url()); + frame->GetSecurityOrigin().CanAccess( + blink::WebSecurityOrigin::Create(document_loader->GetUrl()))) { + return GURL(document_loader->GetUrl()); } } return GURL(weburl);
diff --git a/gpu/angle_end2end_tests_main.cc b/gpu/angle_end2end_tests_main.cc index cb2c65e..cf0206a 100644 --- a/gpu/angle_end2end_tests_main.cc +++ b/gpu/angle_end2end_tests_main.cc
@@ -8,7 +8,6 @@ #include "base/test/launcher/unit_test_launcher.h" #include "base/test/test_suite.h" #include "testing/gmock/include/gmock/gmock.h" -#include "third_party/angle/src/tests/test_utils/ANGLETest.h" namespace { @@ -19,10 +18,12 @@ } // namespace +void ANGLEProcessTestArgs(int *argc, char *argv[]); + int main(int argc, char** argv) { base::CommandLine::Init(argc, argv); testing::InitGoogleMock(&argc, argv); - testing::AddGlobalTestEnvironment(new ANGLETestEnvironment()); + ANGLEProcessTestArgs(&argc, argv); base::TestSuite test_suite(argc, argv); int rt = base::LaunchUnitTestsWithOptions( argc, argv,
diff --git a/gpu/command_buffer/common/shared_image_usage.h b/gpu/command_buffer/common/shared_image_usage.h index 34311eb..45c6cba 100644 --- a/gpu/command_buffer/common/shared_image_usage.h +++ b/gpu/command_buffer/common/shared_image_usage.h
@@ -24,8 +24,6 @@ // TODO(backer): Fold back into SHARED_IMAGE_USAGE_RASTER once RasterInterface // can CPU raster (CopySubImage?) to SkImage. SHARED_IMAGE_USAGE_OOP_RASTERIZATION = 1 << 5, - // Image will be used for RGB emulation in WebGL on Mac. - SHARED_IMAGE_USAGE_RGB_EMULATION = 1 << 6, }; } // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc index bc2c6b0..257ad55f 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc
@@ -445,6 +445,26 @@ texture_passthrough_.reset(); } + void OnMemoryDump(const std::string& dump_name, + base::trace_event::MemoryAllocatorDump* dump, + base::trace_event::ProcessMemoryDump* pmd, + uint64_t client_tracing_id) override { + // Add a |service_guid| which expresses shared ownership between the + // various GPU dumps. + auto client_guid = GetSharedImageGUIDForTracing(mailbox()); + auto service_guid = gl::GetGLTextureServiceGUIDForTracing( + texture_passthrough_->service_id()); + pmd->CreateSharedGlobalAllocatorDump(service_guid); + + int importance = 2; // This client always owns the ref. + pmd->AddOwnershipEdge(client_guid, service_guid, importance); + + auto* gl_image = texture_passthrough_->GetLevelImage( + texture_passthrough_->target(), /*level=*/0); + if (gl_image) + gl_image->OnMemoryDump(pmd, client_tracing_id, dump_name); + } + protected: std::unique_ptr<SharedImageRepresentationGLTexturePassthrough> ProduceGLTexturePassthrough(SharedImageManager* manager, @@ -475,11 +495,7 @@ image_factory_(image_factory) { gl::GLApi* api = gl::g_current_gl_context; api->glGetIntegervFn(GL_MAX_TEXTURE_SIZE, &max_texture_size_); - // When the passthrough command decoder is used, the max_texture_size - // workaround is implemented by ANGLE. Trying to adjust the max size here - // would cause discrepency between what we think the max size is and what - // ANGLE tells the clients. - if (!use_passthrough_ && workarounds.max_texture_size) { + if (workarounds.max_texture_size) { max_texture_size_ = std::min(max_texture_size_, workarounds.max_texture_size); } @@ -767,15 +783,10 @@ SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT)) != 0; GLuint service_id = MakeTextureAndSetParameters( api, target, for_framebuffer_attachment && texture_usage_angle_); - bool is_rgb_emulation = usage & SHARED_IMAGE_USAGE_RGB_EMULATION; + // TODO(piman): RGB emulation gles2::Texture::ImageState image_state = gles2::Texture::UNBOUND; - bool is_bound = false; - if (is_rgb_emulation) - is_bound = image->BindTexImageWithInternalformat(target, GL_RGB); - else - is_bound = image->BindTexImage(target); - if (is_bound) { + if (image->BindTexImage(target)) { image_state = gles2::Texture::BOUND; } else if (use_passthrough_) { image->CopyTexImage(target); @@ -788,8 +799,7 @@ // // - internalformat might be sized, which is wrong for format // - gl_type shouldn't be GL_UNSIGNED_BYTE for RGBA4444 for example. - GLuint internal_format = - is_rgb_emulation ? GL_RGB : image->GetInternalFormat(); + GLuint internal_format = image->GetInternalFormat(); GLenum gl_format = internal_format; GLenum gl_type = GL_UNSIGNED_BYTE;
diff --git a/gpu/config/gpu_control_list.cc b/gpu/config/gpu_control_list.cc index b3c3456..4e28d955 100644 --- a/gpu/config/gpu_control_list.cc +++ b/gpu/config/gpu_control_list.cc
@@ -310,6 +310,22 @@ !pixel_shader_version.Contains(gpu_info.pixel_shader_version)) { return false; } + switch (hardware_overlay) { + case kDontCare: + break; + case kSupported: +#if defined(OS_WIN) + if (!gpu_info.supports_overlays) + return false; +#endif // OS_WIN + break; + case kUnsupported: +#if defined(OS_WIN) + if (gpu_info.supports_overlays) + return false; +#endif // OS_WIN + break; + } return true; }
diff --git a/gpu/config/gpu_control_list.h b/gpu/config/gpu_control_list.h index 64ac36f..d9dc206 100644 --- a/gpu/config/gpu_control_list.h +++ b/gpu/config/gpu_control_list.h
@@ -85,6 +85,12 @@ kVersionStyleUnknown }; + enum SupportedOrNot { + kSupported, + kUnsupported, + kDontCare, + }; + struct GPU_EXPORT Version { NumericOp op; VersionStyle style; @@ -149,6 +155,7 @@ uint32_t gl_reset_notification_strategy; bool direct_rendering; Version gpu_count; + SupportedOrNot hardware_overlay; uint32_t test_group;
diff --git a/gpu/config/gpu_control_list_entry_unittest.cc b/gpu/config/gpu_control_list_entry_unittest.cc index 1d1b47c..b02a5ab 100644 --- a/gpu/config/gpu_control_list_entry_unittest.cc +++ b/gpu/config/gpu_control_list_entry_unittest.cc
@@ -4,6 +4,7 @@ #include <stddef.h> +#include "build/build_config.h" #include "gpu/config/gpu_control_list.h" #include "gpu/config/gpu_control_list_testing_data.h" #include "gpu/config/gpu_info.h" @@ -868,4 +869,17 @@ EXPECT_TRUE(entry.Contains(kOsWin, "10.0", gpu_info)); } +#if defined(OS_WIN) +TEST_F(GpuControlListEntryTest, HardwareOverlay) { + const Entry& entry = GetEntry(kGpuControlListEntryTest_HardwareOverlay); + GPUInfo gpu_info; + gpu_info.gpu.vendor_id = 0x8086; + gpu_info.supports_overlays = true; + EXPECT_FALSE(entry.Contains(kOsWin, "10.0", gpu_info)); + + gpu_info.supports_overlays = false; + EXPECT_TRUE(entry.Contains(kOsWin, "10.0", gpu_info)); +} +#endif // OS_WIN + } // namespace gpu
diff --git a/gpu/config/gpu_control_list_format.txt b/gpu/config/gpu_control_list_format.txt index 1cfd652..e9ff9a1b 100644 --- a/gpu/config/gpu_control_list_format.txt +++ b/gpu/config/gpu_control_list_format.txt
@@ -73,6 +73,10 @@ // "intel_haswell", "intel_cherryview", "intel_broadwell", // "intel_apollolake", "intel_skylake", "intel_geminilake", // "intel_kabylake", "intel_coffeelake". +// 30. "hardware_overlay" is either "supported" or "unsupported". Currently it +// only applies on Windows where hardware overlays may be supported on +// certain Intel GPUs. By default it's "dont_care" and there is no need to +// specify that. // // VERSION includes "op", "style", "value", and "value2". "op" can be any of // the following values: "=", "<", "<=", ">", ">=", "any", "between". "style"
diff --git a/gpu/config/gpu_control_list_testing.json b/gpu/config/gpu_control_list_testing.json index 114173c..3c4cd77 100644 --- a/gpu/config/gpu_control_list_testing.json +++ b/gpu/config/gpu_control_list_testing.json
@@ -814,6 +814,15 @@ "features": [ "test_feature_0" ] + }, + { + "id": 68, + "description": "GpuControlListEntryTest.HardwareOverlay", + "vendor_id": "0x8086", + "hardware_overlay": "unsupported", + "features": [ + "test_feature_0" + ] } ] }
diff --git a/gpu/config/gpu_control_list_testing_arrays_and_structs_autogen.h b/gpu/config/gpu_control_list_testing_arrays_and_structs_autogen.h index 96573345..f543d980 100644 --- a/gpu/config/gpu_control_list_testing_arrays_and_structs_autogen.h +++ b/gpu/config/gpu_control_list_testing_arrays_and_structs_autogen.h
@@ -19,11 +19,13 @@ }; const char* const kDisabledExtensionsForEntry1[2] = { - "test_extension1", "test_extension2", + "test_extension1", + "test_extension2", }; const uint32_t kCrBugsForGpuControlTestingEntry1[2] = { - 1024, 678, + 1024, + 678, }; const uint32_t kDeviceIDsForGpuControlTestingEntry1[1] = { @@ -71,7 +73,8 @@ }; const uint32_t kDeviceIDsForGpuControlTestingEntry7[2] = { - 0x1023, 0x0640, + 0x1023, + 0x0640, }; const int kFeatureListForGpuControlTestingEntry8[1] = { @@ -92,8 +95,9 @@ 0, // gl_reset_notification_strategy true, // direct_rendering {GpuControlList::kUnknown, GpuControlList::kVersionStyleNumerical, nullptr, - nullptr}, // gpu_count - 0, // test_group + nullptr}, // gpu_count + GpuControlList::kDontCare, // hardware_overlay + 0, // test_group }; const int kFeatureListForGpuControlTestingEntry10[1] = { @@ -110,8 +114,9 @@ 0, // gl_reset_notification_strategy true, // direct_rendering {GpuControlList::kUnknown, GpuControlList::kVersionStyleNumerical, nullptr, - nullptr}, // gpu_count - 0, // test_group + nullptr}, // gpu_count + GpuControlList::kDontCare, // hardware_overlay + 0, // test_group }; const int kFeatureListForGpuControlTestingEntry11[1] = { @@ -128,8 +133,9 @@ 0, // gl_reset_notification_strategy true, // direct_rendering {GpuControlList::kUnknown, GpuControlList::kVersionStyleNumerical, nullptr, - nullptr}, // gpu_count - 0, // test_group + nullptr}, // gpu_count + GpuControlList::kDontCare, // hardware_overlay + 0, // test_group }; const int kFeatureListForGpuControlTestingEntry12[1] = { @@ -137,7 +143,10 @@ }; const GpuControlList::GLStrings kGLStringsForGpuControlTestingEntry12 = { - "NVIDIA", nullptr, nullptr, nullptr, + "NVIDIA", + nullptr, + nullptr, + nullptr, }; const int kFeatureListForGpuControlTestingEntry13[1] = { @@ -145,7 +154,10 @@ }; const GpuControlList::GLStrings kGLStringsForGpuControlTestingEntry13 = { - "X\\.Org.*", nullptr, nullptr, nullptr, + "X\\.Org.*", + nullptr, + nullptr, + nullptr, }; const int kFeatureListForGpuControlTestingEntry14[1] = { @@ -153,7 +165,10 @@ }; const GpuControlList::GLStrings kGLStringsForGpuControlTestingEntry14 = { - nullptr, ".*GeForce.*", nullptr, nullptr, + nullptr, + ".*GeForce.*", + nullptr, + nullptr, }; const int kFeatureListForGpuControlTestingEntry15[1] = { @@ -161,7 +176,10 @@ }; const GpuControlList::GLStrings kGLStringsForGpuControlTestingEntry15 = { - nullptr, "(?i).*software.*", nullptr, nullptr, + nullptr, + "(?i).*software.*", + nullptr, + nullptr, }; const int kFeatureListForGpuControlTestingEntry16[1] = { @@ -169,7 +187,10 @@ }; const GpuControlList::GLStrings kGLStringsForGpuControlTestingEntry16 = { - nullptr, nullptr, ".*GL_SUN_slice_accum", nullptr, + nullptr, + nullptr, + ".*GL_SUN_slice_accum", + nullptr, }; const int kFeatureListForGpuControlTestingEntry17[1] = { @@ -222,7 +243,10 @@ const GpuControlList::GLStrings kGLStringsForGpuControlTestingEntry22Exception0 = { - nullptr, ".*mesa.*", nullptr, nullptr, + nullptr, + ".*mesa.*", + nullptr, + nullptr, }; const int kFeatureListForGpuControlTestingEntry23[1] = { @@ -239,16 +263,20 @@ 0, // gl_reset_notification_strategy true, // direct_rendering {GpuControlList::kUnknown, GpuControlList::kVersionStyleNumerical, nullptr, - nullptr}, // gpu_count - 0, // test_group + nullptr}, // gpu_count + GpuControlList::kDontCare, // hardware_overlay + 0, // test_group }; const int kFeatureListForGpuControlTestingEntry24[3] = { - TEST_FEATURE_0, TEST_FEATURE_1, TEST_FEATURE_2, + TEST_FEATURE_0, + TEST_FEATURE_1, + TEST_FEATURE_2, }; const int kFeatureListForGpuControlTestingEntry25[2] = { - TEST_FEATURE_1, TEST_FEATURE_2, + TEST_FEATURE_1, + TEST_FEATURE_2, }; const int kFeatureListForGpuControlTestingEntry26[1] = { @@ -264,7 +292,10 @@ }; const char* const kMachineModelNameForEntry27[4] = { - "Nexus 4", "XT1032", "GT-.*", "SCH-.*", + "Nexus 4", + "XT1032", + "GT-.*", + "SCH-.*", }; const GpuControlList::MachineModelInfo kMachineModelInfoForEntry27 = { @@ -372,7 +403,8 @@ }; const uint32_t kDeviceIDsForGpuControlTestingEntry36[2] = { - 0x0166, 0x0168, + 0x0166, + 0x0168, }; const int kFeatureListForGpuControlTestingEntry37[1] = { @@ -405,8 +437,9 @@ 0, // gl_reset_notification_strategy true, // direct_rendering {GpuControlList::kUnknown, GpuControlList::kVersionStyleNumerical, nullptr, - nullptr}, // gpu_count - 0, // test_group + nullptr}, // gpu_count + GpuControlList::kDontCare, // hardware_overlay + 0, // test_group }; const int kFeatureListForGpuControlTestingEntry41[1] = { @@ -477,8 +510,9 @@ 0, // gl_reset_notification_strategy true, // direct_rendering {GpuControlList::kUnknown, GpuControlList::kVersionStyleNumerical, nullptr, - nullptr}, // gpu_count - 0, // test_group + nullptr}, // gpu_count + GpuControlList::kDontCare, // hardware_overlay + 0, // test_group }; const int kFeatureListForGpuControlTestingEntry49[1] = { @@ -515,7 +549,10 @@ const GpuControlList::GLStrings kGLStringsForGpuControlTestingEntry52Exception0 = { - nullptr, ".*mesa.*", nullptr, nullptr, + nullptr, + ".*mesa.*", + nullptr, + nullptr, }; const int kFeatureListForGpuControlTestingEntry53[1] = { @@ -535,11 +572,13 @@ }; const char* const kDisabledExtensionsForEntry55[2] = { - "test_extension2", "test_extension1", + "test_extension2", + "test_extension1", }; const char* const kDisabledExtensionsForEntry56[2] = { - "test_extension3", "test_extension2", + "test_extension3", + "test_extension2", }; const int kFeatureListForGpuControlTestingEntry57[1] = { @@ -556,8 +595,9 @@ 0, // gl_reset_notification_strategy false, // direct_rendering {GpuControlList::kUnknown, GpuControlList::kVersionStyleNumerical, nullptr, - nullptr}, // gpu_count - 0, // test_group + nullptr}, // gpu_count + GpuControlList::kDontCare, // hardware_overlay + 0, // test_group }; const int kFeatureListForGpuControlTestingEntry58[1] = { @@ -578,8 +618,9 @@ 0, // gl_reset_notification_strategy true, // direct_rendering {GpuControlList::kUnknown, GpuControlList::kVersionStyleNumerical, nullptr, - nullptr}, // gpu_count - 1, // test_group + nullptr}, // gpu_count + GpuControlList::kDontCare, // hardware_overlay + 1, // test_group }; const int kFeatureListForGpuControlTestingEntry60[1] = { @@ -596,8 +637,9 @@ 0, // gl_reset_notification_strategy true, // direct_rendering {GpuControlList::kUnknown, GpuControlList::kVersionStyleNumerical, nullptr, - nullptr}, // gpu_count - 2, // test_group + nullptr}, // gpu_count + GpuControlList::kDontCare, // hardware_overlay + 2, // test_group }; const int kFeatureListForGpuControlTestingEntry61[1] = { @@ -605,7 +647,8 @@ }; const GpuSeriesType kGpuSeriesForEntry61[2] = { - GpuSeriesType::kIntelSkyLake, GpuSeriesType::kIntelKabyLake, + GpuSeriesType::kIntelSkyLake, + GpuSeriesType::kIntelKabyLake, }; const int kFeatureListForGpuControlTestingEntry62[1] = { @@ -660,6 +703,25 @@ nullptr}, // driver_date }; +const int kFeatureListForGpuControlTestingEntry68[1] = { + TEST_FEATURE_0, +}; + +const GpuControlList::More kMoreForEntry68 = { + GpuControlList::kGLTypeNone, // gl_type + {GpuControlList::kUnknown, GpuControlList::kVersionStyleNumerical, nullptr, + nullptr}, // gl_version + {GpuControlList::kUnknown, GpuControlList::kVersionStyleNumerical, nullptr, + nullptr}, // pixel_shader_version + false, // in_process_gpu + 0, // gl_reset_notification_strategy + true, // direct_rendering + {GpuControlList::kUnknown, GpuControlList::kVersionStyleNumerical, nullptr, + nullptr}, // gpu_count + GpuControlList::kUnsupported, // hardware_overlay + 0, // test_group +}; + } // namespace gpu #endif // GPU_CONFIG_GPU_CONTROL_LIST_TESTING_ARRAYS_AND_STRUCTS_AUTOGEN_H_
diff --git a/gpu/config/gpu_control_list_testing_autogen.cc b/gpu/config/gpu_control_list_testing_autogen.cc index ad00d6ac..7601e14f 100644 --- a/gpu/config/gpu_control_list_testing_autogen.cc +++ b/gpu/config/gpu_control_list_testing_autogen.cc
@@ -2036,6 +2036,36 @@ 0, // exceptions count nullptr, // exceptions }, + { + 68, // id + "GpuControlListEntryTest.HardwareOverlay", + base::size(kFeatureListForGpuControlTestingEntry68), // features size + kFeatureListForGpuControlTestingEntry68, // features + 0, // DisabledExtensions size + nullptr, // DisabledExtensions + 0, // DisabledWebGLExtensions size + nullptr, // DisabledWebGLExtensions + 0, // CrBugs size + nullptr, // CrBugs + { + GpuControlList::kOsAny, // os_type + {GpuControlList::kUnknown, GpuControlList::kVersionStyleNumerical, + nullptr, nullptr}, // os_version + 0x8086, // vendor_id + 0, // DeviceIDs size + nullptr, // DeviceIDs + GpuControlList::kMultiGpuCategoryNone, // multi_gpu_category + GpuControlList::kMultiGpuStyleNone, // multi_gpu_style + nullptr, // driver info + nullptr, // GL strings + nullptr, // machine model info + 0, // gpu_series size + nullptr, // gpu_series + &kMoreForEntry68, // more data + }, + 0, // exceptions count + nullptr, // exceptions + }, }; -const size_t kGpuControlListTestingEntryCount = 67; +const size_t kGpuControlListTestingEntryCount = 68; } // namespace gpu
diff --git a/gpu/config/gpu_control_list_testing_entry_enums_autogen.h b/gpu/config/gpu_control_list_testing_entry_enums_autogen.h index d896d1a..ea120e72 100644 --- a/gpu/config/gpu_control_list_testing_entry_enums_autogen.h +++ b/gpu/config/gpu_control_list_testing_entry_enums_autogen.h
@@ -80,6 +80,7 @@ kGpuControlListEntryTest_GpuSeriesSecondary = 64, kGpuControlListEntryTest_GpuSeriesInException = 65, kGpuControlListEntryTest_MultipleDrivers = 66, + kGpuControlListEntryTest_HardwareOverlay = 67, }; } // namespace gpu
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json index 6bfc6f5..957e28583 100644 --- a/gpu/config/gpu_driver_bug_list.json +++ b/gpu/config/gpu_driver_bug_list.json
@@ -3046,7 +3046,7 @@ { "id": 284, "cr_bugs": [913301], - "description": "Clamp texture's BASE_LEVEL/MAX_LEVEL for GenerateMipmap", + "description": "Clamp texture's BASE_LEVEL/MAX_LEVEL for GenerateMipmap on Mac", "os": { "type": "macosx" }, @@ -3065,6 +3065,36 @@ "features": [ "use_virtualized_gl_contexts" ] + }, + { + "id": 286, + "cr_bugs": [908069], + "description": "Video corruption on Intel HD 530 without hardware overlay support", + "vendor_id": "0x8086", + "device_id": ["0x1912"], + "os": { + "type": "win" + }, + "driver_version": { + "op": ">=", + "value": "24" + }, + "hardware_overlay": "unsupported", + "features": [ + "disable_direct_composition" + ] + }, + { + "id": 287, + "cr_bugs": [913301], + "description": "Clamp texture's BASE_LEVEL/MAX_LEVEL for GenerateMipmap on Linux/AMD", + "os": { + "type": "linux" + }, + "vendor_id": "0x1002", + "features": [ + "clamp_texture_base_level_and_max_level" + ] } ] }
diff --git a/gpu/config/process_json.py b/gpu/config/process_json.py index 17c942f..c4faaf2 100755 --- a/gpu/config/process_json.py +++ b/gpu/config/process_json.py
@@ -343,6 +343,19 @@ data_file.write('GpuControlList::kGLType%s, // gl_type\n' % map[gl_type]) +def write_supported_or_not(feature_value, feature_name, data_file): + if feature_value is None: + feature_value = 'dont_care' + map = { + 'supported': 'Supported', + 'unsupported': 'Unsupported', + 'dont_care': 'DontCare', + } + assert map.has_key(feature_value) + data_file.write('GpuControlList::k%s, // %s\n' % + (map[feature_value], feature_name)) + + def write_conditions(entry_id, is_exception, exception_id, entry, unique_symbol_id, data_file, data_helper_file, _data_exception_file): @@ -367,6 +380,7 @@ gl_reset_notification_strategy = None direct_rendering = True gpu_count = None + hardware_overlay = None test_group = 0 machine_model_name = None machine_model_version = None @@ -442,6 +456,8 @@ direct_rendering = False elif key == 'gpu_count': gpu_count = entry[key] + elif key == 'hardware_overlay': + hardware_overlay = entry[key] elif key == 'test_group': assert entry[key] > 0 test_group = entry[key] @@ -487,11 +503,12 @@ # group a bunch of less used conditions if (gl_version != None or pixel_shader_version != None or in_process_gpu or gl_reset_notification_strategy != None or (not direct_rendering) or - gpu_count != None or test_group != 0): + gpu_count != None or hardware_overlay != None or test_group != 0): write_entry_more_data(entry_id, is_exception, exception_id, gl_type, gl_version, pixel_shader_version, in_process_gpu, gl_reset_notification_strategy, direct_rendering, - gpu_count, test_group, data_file, data_helper_file) + gpu_count, hardware_overlay, test_group, data_file, + data_helper_file) else: data_file.write('nullptr, // more conditions\n') @@ -533,7 +550,8 @@ def write_entry_more_data(entry_id, is_exception, exception_id, gl_type, gl_version, pixel_shader_version, in_process_gpu, gl_reset_notification_strategy, direct_rendering, - gpu_count, test_group, data_file, data_helper_file): + gpu_count, hardware_overlay, test_group, data_file, + data_helper_file): # write more data var_name = 'kMoreForEntry' + str(entry_id) if is_exception: @@ -549,6 +567,7 @@ gl_reset_notification_strategy) write_boolean_value(direct_rendering, 'direct_rendering', data_helper_file) write_version(gpu_count, 'gpu_count', data_helper_file) + write_supported_or_not(hardware_overlay, 'hardware_overlay', data_helper_file) write_integer_value(test_group, 'test_group', data_helper_file) data_helper_file.write('};\n\n') # reference more data in entry
diff --git a/infra/config/global/cr-buildbucket.cfg b/infra/config/global/cr-buildbucket.cfg index e45e58a..408bd642 100644 --- a/infra/config/global/cr-buildbucket.cfg +++ b/infra/config/global/cr-buildbucket.cfg
@@ -515,26 +515,6 @@ } builder_mixins { - name: "webkit-ci" - recipe { - properties: "mastername:chromium.webkit" - } -} - -# TODO(crbug.com/818301): Get rid of this once all former chromium.webkit -# builders are prod on LUCI and chromium.webkit Buildbot master is shutdown. -builder_mixins { - name: "webkit-ci-migration" - recipe { - # This tells Buildbucket to look at migration status of corresponding - # chromium.webkit builder on luci-migration app, regardless of 'mastername' - # property. Useful when moving builder to LUCI and changing their masters - # at the same time. - properties: "luci_migration_master_name:chromium.webkit" - } -} - -builder_mixins { name: "win" dimensions: "os:Windows" } @@ -1973,7 +1953,6 @@ name: "WebKit Linux Trusty MSAN" dimensions: "os:Ubuntu-14.04" mixins: "memory-ci" - mixins: "webkit-ci-migration" } builders { name: "Mac ASAN Release Media" @@ -2018,7 +1997,6 @@ name: "WebKit Linux Trusty ASAN" dimensions: "os:Ubuntu-14.04" mixins: "memory-ci" - mixins: "webkit-ci-migration" } builders { name: "Libfuzzer Upload Mac ASan" @@ -2026,6 +2004,7 @@ dimensions: "cores:24" mixins: "fuzz-ci" mixins: "libfuzzer" + execution_timeout_secs: 14400 # 4 hours } builders { name: "Libfuzzer Upload Windows ASan" @@ -2080,7 +2059,6 @@ name: "WebKit Linux Trusty Leak" dimensions: "os:Ubuntu-14.04" mixins: "memory-ci" - mixins: "webkit-ci-migration" } builders { name: "Linux ChromiumOS MSan Tests" @@ -2140,7 +2118,6 @@ name: "WebKit Mac10.13 (retina)" dimensions: "os:Mac-10.13" mixins: "mac-ci" - mixins: "webkit-ci-migration" } builders { name: "Afl Upload Linux ASan" @@ -2214,11 +2191,6 @@ mixins: "fyi-ci" } builders { - name: "linux-gtest-hackathon-dbg" - dimensions: "os:Ubuntu-14.04" - mixins: "fyi-ci" - } - builders { name: "win-annotator-rel" dimensions: "os:Windows-10" execution_timeout_secs: 57600 # 16h @@ -2503,7 +2475,6 @@ name: "WebKit Win10" dimensions: "os:Windows-10" mixins: "win-ci" - mixins: "webkit-ci-migration" } builders { name: "win32-dbg"
diff --git a/infra/config/global/luci-milo.cfg b/infra/config/global/luci-milo.cfg index 9dd8016..5c66089 100644 --- a/infra/config/global/luci-milo.cfg +++ b/infra/config/global/luci-milo.cfg
@@ -152,11 +152,6 @@ alt: "Chromium Perf FYI console" } links { - text: "webkit" - url: "/p/chromium/g/chromium.webkit" - alt: "Chromium WebKit console" - } - links { text: "webrtc" url: "/p/chromium/g/chromium.webrtc" alt: "Chromium WebRTC console" @@ -231,7 +226,6 @@ console_ids: "chromium/chromium.chrome" console_ids: "chromium/chromium.memory" console_ids: "chromium/chromium.gpu" - console_ids: "chromium/chromium.webkit" } console_groups { console_ids: "chromium/chromium.android" @@ -414,6 +408,11 @@ short_name: "det" } builders { + name: "buildbucket/luci.chromium.ci/WebKit Win10" + category: "chromium.win" + short_name: "wbk" + } + builders { name: "buildbucket/luci.chromium.ci/Mac Builder" category: "chromium.mac|release|builder" short_name: "bld" @@ -489,6 +488,10 @@ short_name: "slim" } builders { + name: "buildbucket/luci.chromium.ci/WebKit Mac10.13 (retina)" + category: "chromium.mac|wbk" + } + builders { name: "buildbucket/luci.chromium.ci/Linux Builder" category: "chromium.linux|release" short_name: "bld" @@ -690,6 +693,21 @@ short_name: "cfi" } builders { + name: "buildbucket/luci.chromium.ci/WebKit Linux Trusty ASAN" + category: "chromium.memory|linux|webkit" + short_name: "asn" + } + builders { + name: "buildbucket/luci.chromium.ci/WebKit Linux Trusty MSAN" + category: "chromium.memory|linux|webkit" + short_name: "msn" + } + builders { + name: "buildbucket/luci.chromium.ci/WebKit Linux Trusty Leak" + category: "chromium.memory|linux|webkit" + short_name: "lk" + } + builders { name: "buildbot/chromium.memory/Linux Chromium OS ASan LSan Builder" name: "buildbucket/luci.chromium.ci/Linux Chromium OS ASan LSan Builder" category: "chromium.memory|cros|asan" @@ -719,31 +737,6 @@ category: "chromium.memory|android" short_name: "cfi" } - builders { - name: "buildbucket/luci.chromium.ci/WebKit Win10" - category: "chromium.webkit|win|tst" - short_name: "10" - } - builders { - name: "buildbucket/luci.chromium.ci/WebKit Mac10.13 (retina)" - category: "chromium.webkit|mac" - short_name: "13r" - } - builders { - name: "buildbot/chromium.webkit/WebKit Linux Trusty ASAN" - category: "chromium.webkit|linux|release" - short_name: "asn" - } - builders { - name: "buildbot/chromium.webkit/WebKit Linux Trusty MSAN" - category: "chromium.webkit|linux|release" - short_name: "msn" - } - builders { - name: "buildbot/chromium.webkit/WebKit Linux Trusty Leak" - category: "chromium.webkit|linux|release" - short_name: "lk" - } } consoles { @@ -807,6 +800,10 @@ name: "buildbucket/luci.chromium.ci/Windows deterministic" short_name: "det" } + builders { + name: "buildbucket/luci.chromium.ci/WebKit Win10" + short_name: "wbk" + } } consoles { @@ -891,6 +888,10 @@ category: "ios" short_name: "slim" } + builders { + name: "buildbucket/luci.chromium.ci/WebKit Mac10.13 (retina)" + category: "wbk" + } } consoles { @@ -1122,6 +1123,21 @@ short_name: "cfi" } builders { + name: "buildbucket/luci.chromium.ci/WebKit Linux Trusty ASAN" + category: "linux|webkit" + short_name: "asn" + } + builders { + name: "buildbucket/luci.chromium.ci/WebKit Linux Trusty MSAN" + category: "linux|webkit" + short_name: "msn" + } + builders { + name: "buildbucket/luci.chromium.ci/WebKit Linux Trusty Leak" + category: "linux|webkit" + short_name: "lk" + } + builders { name: "buildbot/chromium.memory/Linux Chromium OS ASan LSan Builder" name: "buildbucket/luci.chromium.ci/Linux Chromium OS ASan LSan Builder" category: "cros|asan" @@ -1155,40 +1171,6 @@ consoles { header_id: "chromium" - id: "chromium.webkit" - name: "chromium.webkit" - repo_url: "https://chromium.googlesource.com/chromium/src" - refs: "refs/heads/master" - manifest_name: "REVISION" - builders { - name: "buildbucket/luci.chromium.ci/WebKit Win10" - category: "win|tst" - short_name: "10" - } - builders { - name: "buildbucket/luci.chromium.ci/WebKit Mac10.13 (retina)" - category: "mac" - short_name: "13r" - } - builders { - name: "buildbot/chromium.webkit/WebKit Linux Trusty ASAN" - category: "linux|release" - short_name: "asn" - } - builders { - name: "buildbot/chromium.webkit/WebKit Linux Trusty MSAN" - category: "linux|release" - short_name: "msn" - } - builders { - name: "buildbot/chromium.webkit/WebKit Linux Trusty Leak" - category: "linux|release" - short_name: "lk" - } -} - -consoles { - header_id: "chromium" id: "chromium.perf" name: "chromium.perf" repo_url: "https://chromium.googlesource.com/chromium/src" @@ -2710,10 +2692,6 @@ category: "linux" } builders { - name: "buildbucket/luci.chromium.ci/linux-gtest-hackathon-dbg" - category: "linux" - } - builders { name: "buildbucket/luci.chromium.ci/Mojo Android" category: "mojo" short_name: "and"
diff --git a/infra/config/global/luci-scheduler.cfg b/infra/config/global/luci-scheduler.cfg index c969682..3b9b2fb 100644 --- a/infra/config/global/luci-scheduler.cfg +++ b/infra/config/global/luci-scheduler.cfg
@@ -5085,27 +5085,3 @@ builder: "WebRTC Chromium FYI Win Builder (dbg)" } } - -# TODO(ericale): Remove once hackathon is over. -trigger { - id: "gtest-hackathon-gitiles-trigger" - acl_sets: "default" - - gitiles: { - repo: "https://chromium.googlesource.com/chromium/src.git" - refs: "refs/experimental/gtest-hackathon" - } - - triggers: "linux-gtest-hackathon-dbg" -} - -# TODO(ericale): Remove once hackathon is over. -job { - id: "linux-gtest-hackathon-dbg" - acl_sets: "default" - buildbucket: { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "linux-gtest-hackathon-dbg" - } -}
diff --git a/ios/build/bots/scripts/run.py b/ios/build/bots/scripts/run.py index 7d23f0d..5ae6fd7 100755 --- a/ios/build/bots/scripts/run.py +++ b/ios/build/bots/scripts/run.py
@@ -48,6 +48,7 @@ retry=args.retries, shards=args.shards, xcode_path=args.xcode_path, + test_cases=args.test_cases ) elif args.replay_path != 'NO_PATH': tr = test_runner.WprProxySimulatorTestRunner(
diff --git a/ios/build/bots/scripts/xcodebuild_runner.py b/ios/build/bots/scripts/xcodebuild_runner.py index c4a8ce2..a178364 100644 --- a/ios/build/bots/scripts/xcodebuild_runner.py +++ b/ios/build/bots/scripts/xcodebuild_runner.py
@@ -14,7 +14,6 @@ import re import shutil import subprocess -import tempfile import time import test_runner @@ -60,6 +59,8 @@ for summary in root_summary['TestableSummaries']: failed_egtests = [] passed_egtests = [] + if not summary['Tests']: + continue for test_suite in summary['Tests'][0]['Subtests'][0]['Subtests']: for test in test_suite['Subtests']: if test['TestStatus'] == 'Success': @@ -102,13 +103,17 @@ root = plistlib.readPlist(plist_path) for action in root['Actions']: - summary_plist = os.path.join(os.path.dirname(plist_path), - action['ActionResult']['TestSummaryPath']) - summary = test_status_summary(summary_plist) - test_results['failed'] = summary['failed'] - test_results['passed'] = summary['passed'] + action_result = action['ActionResult'] + if action_result['TestsCount'] == 0 and action_result['ErrorCount'] != 0: + test_results['failed']['TESTS_DID_NOT_START'] = [] + else: + summary_plist = os.path.join(os.path.dirname(plist_path), + action_result['TestSummaryPath']) + summary = test_status_summary(summary_plist) + test_results['failed'] = summary['failed'] + test_results['passed'] = summary['passed'] - for error_summary in action['ActionResult']['ErrorSummaries']: + for error_summary in action_result['ErrorSummaries']: test_results['errors'].append(error_summary['Message']) # If xcodebuild finished with non-zero status and no failure/error # in the Info.plist log. @@ -275,7 +280,7 @@ print 'No failures in %s' % info_plist_path return - screenshot_regex = re.compile(r'Screenshots:\s\{(\n.*)*\n}') + screenshot_regex = re.compile(r'Screenshots:\s\{(\n.*)+?\n}') for failure_summary in plist['TestFailureSummaries']: screenshots = screenshot_regex.search(failure_summary['Message']) test_case_folder = os.path.join( @@ -359,6 +364,7 @@ def launch(self): """Launches tests using xcodebuild.""" initial_command = [] + cmd_list = [] self.test_results['attempts'] = [] # total number of attempts is self.retries+1 @@ -370,7 +376,10 @@ self.destination, self.shards) initial_command = list(cmd_list) - else: + # (http://crbug.com/916620) If tests has not started, repeat the command + # otherwise re-init based on list of failed tests. + elif 'TESTS_DID_NOT_START' not in self.test_results[ + 'attempts'][-1]['failed']: cmd_list = self._make_cmd_list_for_failed_tests( self.test_results['attempts'][-1]['failed'], outdir_attempt) @@ -411,7 +420,12 @@ """ if not egtests_app: raise test_runner.AppNotFoundError('Egtests is not found!') - xctestrun = tempfile.mkstemp()[1] + xctestrun = os.path.join( + os.path.abspath(os.path.join(self.out_dir, os.pardir)), + 'run_%d.xctestrun' % int(time.time())) + if not os.path.exists(xctestrun): + with open(xctestrun, 'w'): + pass # Creates a dict with data about egtests to run - fill all required fields: # egtests_module, egtest_app_path, egtests_xctest_path and # filtered tests if filter is specified. @@ -436,12 +450,14 @@ Returns: A list of strings forming the command to launch the test. """ - return ['xcodebuild', 'test-without-building', - '-xctestrun', self.fill_xctest_run(egtests_app), - '-resultBundlePath', out_dir, - '-parallel-testing-enabled', 'YES', - '-destination', destination, - '-parallel-testing-worker-count', str(shards)] + cmd = ['xcodebuild', 'test-without-building', + '-xctestrun', self.fill_xctest_run(egtests_app), + '-destination', destination, + '-resultBundlePath', out_dir] + if self.shards > 1: + cmd += ['-parallel-testing-enabled', 'YES', + '-parallel-testing-worker-count', str(shards)] + return cmd class SimulatorParallelTestRunner(test_runner.SimulatorTestRunner): @@ -457,7 +473,8 @@ mac_toolchain=None, retry=1, shards=1, - xcode_path=None + xcode_path=None, + test_cases=None ): """Initializes a new instance of SimulatorParallelTestRunner class. @@ -471,6 +488,8 @@ retry: (int) A number to retry test run, will re-run only failed tests. shards: (int) A number of shards. Default is 1. xcode_path: (str) A path to Xcode.app folder. + test_cases: (list) List of tests to be included in the test run. + None or [] to include all tests. Raises: AppNotFoundError: If the given app does not exist. @@ -487,6 +506,7 @@ self.retry = retry or 1 self.shards = shards or 1 self.xcode_path = xcode_path + self.test_cases = test_cases self._init_sharding_data() self.logs = collections.OrderedDict() self.test_results = collections.OrderedDict() @@ -515,6 +535,7 @@ 'destination': 'platform=iOS Simulator,OS=%s,name=%s' % ( self.version, self.platform), 'shards': self.shards, + 'test_cases': self.test_cases } ] @@ -532,16 +553,16 @@ """Launches tests using xcodebuild.""" destinaion_folder = lambda dest: dest.replace( 'platform=iOS Simulator,', '').replace(',name=', ' ').replace('OS=', '') - launch_commands = [ - LaunchCommand(EgtestsApp(params['app']), - params['destination'], - shards=params['shards'], - retries=self.retry, - out_dir=os.path.join( - self.out_dir, - destinaion_folder(params['destination'])), - env=self.get_launch_env()) - for params in self.sharding_data] + launch_commands = [] + for params in self.sharding_data: + launch_commands.append(LaunchCommand( + EgtestsApp(params['app'], filtered_tests=params['test_cases']), + params['destination'], + shards=params['shards'], + retries=self.retry, + out_dir=os.path.join(self.out_dir, + destinaion_folder(params['destination'])), + env=self.get_launch_env())) pool = multiprocessing.pool.ThreadPool(len(launch_commands)) self.test_results['commands'] = []
diff --git a/ios/build/bots/scripts/xcodebuild_runner_test.py b/ios/build/bots/scripts/xcodebuild_runner_test.py index 5322241d..e484f0a 100644 --- a/ios/build/bots/scripts/xcodebuild_runner_test.py +++ b/ios/build/bots/scripts/xcodebuild_runner_test.py
@@ -103,13 +103,13 @@ type(mock_egtest).egtests_path = mock.PropertyMock( return_value=_EGTESTS_APP_PATH) cmd = xcodebuild_runner.LaunchCommand( - mock_egtest, destination, shards=1, retries=1, out_dir=_OUT_DIR) + mock_egtest, destination, shards=3, retries=1, out_dir=_OUT_DIR) self.assertEqual(['xcodebuild', 'test-without-building', '-xctestrun', '/tmp/temp_file.xctestrun', - '-resultBundlePath', 'out/dir', - '-parallel-testing-enabled', 'YES', '-destination', 'platform=iOS Simulator,OS=12.0,name=iPhone X', + '-resultBundlePath', 'out/dir', + '-parallel-testing-enabled', 'YES', '-parallel-testing-worker-count', '3'], cmd.command(egtests_app=mock_egtest, out_dir=_OUT_DIR,
diff --git a/ios/chrome/app/application_delegate/app_state.mm b/ios/chrome/app/application_delegate/app_state.mm index 77ed3c1..36a35e8 100644 --- a/ios/chrome/app/application_delegate/app_state.mm +++ b/ios/chrome/app/application_delegate/app_state.mm
@@ -38,7 +38,6 @@ #import "ios/chrome/browser/metrics/previous_session_info.h" #import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.h" -#include "ios/chrome/browser/ui/background_generator.h" #import "ios/chrome/browser/ui/browser_view_controller.h" #import "ios/chrome/browser/ui/commands/application_commands.h" #import "ios/chrome/browser/ui/commands/browser_commands.h"
diff --git a/ios/chrome/app/resources/chrome_localize_strings_config.plist b/ios/chrome/app/resources/chrome_localize_strings_config.plist index 2de181b..c0f2373 100644 --- a/ios/chrome/app/resources/chrome_localize_strings_config.plist +++ b/ios/chrome/app/resources/chrome_localize_strings_config.plist
@@ -36,6 +36,12 @@ </dict> <dict> <key>input</key> + <string>IDS_IOS_INTENTS_SEARCH_IN_CHROME_DESCRIPTION</string> + <key>output</key> + <string>k0Ho6W</string> + </dict> + <dict> + <key>input</key> <string>IDS_IOS_INTENTS_SEARCH_IN_CHROME_TITLE</string> <key>output</key> <string>Z6KvRw</string>
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index f0e6e5d..b88a5139 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -964,7 +964,7 @@ Syncing... </message> <message name="IDS_IOS_OMNIBOX_POPUP_APPEND" desc="Label for the accessibility action for the address and search bar autocomplete suggestion. It replaces the text in the search bar by the suggestion. [Read by Text-to-Speech]"> - Select text + Refine </message> <message name="IDS_IOS_OMNIBOX_POPUP_SWITCH_TO_OPEN_TAB" desc="Label for the accessibility action for the address and search bar autocomplete suggestion. Using this will switch to the already opened tab corresponding to the suggestion. [Read by Text-to-Speech]"> Switch to existing tab
diff --git a/ios/chrome/app/strings/resources/ios_strings_it.xtb b/ios/chrome/app/strings/resources/ios_strings_it.xtb index 74133dbb..d242136 100644 --- a/ios/chrome/app/strings/resources/ios_strings_it.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_it.xtb
@@ -346,7 +346,7 @@ <translation id="6482629121755362506"><ph name="NUMBER_OF_SELECTED_BOOKMARKS" /> elementi eliminati</translation> <translation id="6541915733953096570">Ultima ora</translation> <translation id="6548479190262846511">Non è stata trovata alcuna password per questo sito</translation> -<translation id="6642362222295953972">Passa alle schede esistenti</translation> +<translation id="6642362222295953972">Passa alla scheda esistente</translation> <translation id="6643016212128521049">Cancella</translation> <translation id="6656103420185847513">Modifica cartella</translation> <translation id="6657585470893396449">Password</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_no.xtb b/ios/chrome/app/strings/resources/ios_strings_no.xtb index b689029..2daf61a 100644 --- a/ios/chrome/app/strings/resources/ios_strings_no.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_no.xtb
@@ -62,7 +62,7 @@ <translation id="1820259098641718022">Lagt til i leselisten</translation> <translation id="1821253160463689938">Bruker informasjonskapsler til å huske preferansene dine, selv om du ikke går til de sidene</translation> <translation id="1876721852596493031">Send bruksdata</translation> -<translation id="1880677175115548835">Markér tekst</translation> +<translation id="1880677175115548835">Merk tekst</translation> <translation id="1886928167269928266">Tidenes morgen</translation> <translation id="1911619930368729126">Last opp til Google Disk</translation> <translation id="1941314575388338491">Dobbelttrykk for å kopiere.</translation>
diff --git a/ios/chrome/browser/find_in_page/resources/find_in_page.js b/ios/chrome/browser/find_in_page/resources/find_in_page.js index 048e88b..8d6b53c 100644 --- a/ios/chrome/browser/find_in_page/resources/find_in_page.js +++ b/ios/chrome/browser/find_in_page/resources/find_in_page.js
@@ -276,7 +276,7 @@ /** * The list of frame documents. - * TODO(justincohen): x-domain frames won't work. + * TODO(crbug.com/895529): x-domain frames won't work. * @type {Array<Document>} */ let frameDocs_ = []; @@ -447,7 +447,7 @@ whether the text was found and int idicates text position. */ __gCrWeb.findInPage.pumpSearch = function(timeout) { - // TODO(justincohen): It would be better if this DCHECKed. + // TODO(crbug.com/895531): It would be better if this DCHECKed. if (searchInProgress_ == false) return NO_RESULTS; @@ -884,7 +884,7 @@ // only scroll the window, not any scrollable containers in the DOM itself. So // for now this function returns false if the element is scrolled outside the // viewable area of its ancestors. - // TODO(justincohen): handle scrolling within the DOM. + // TODO(crbug.com/915357): handle scrolling within the DOM. let bodyHeight = getBodyHeight_(); let bodyWidth = getBodyWidth_();
diff --git a/ios/chrome/browser/metrics/ukm_egtest.mm b/ios/chrome/browser/metrics/ukm_egtest.mm index 9a7bbd291..6917122 100644 --- a/ios/chrome/browser/metrics/ukm_egtest.mm +++ b/ios/chrome/browser/metrics/ukm_egtest.mm
@@ -48,7 +48,7 @@ using chrome_test_util::SettingsDoneButton; using chrome_test_util::SettingsMenuPrivacyButton; using chrome_test_util::SignOutAccountsButton; -using chrome_test_util::SyncSwitchCell; +using chrome_test_util::LegacySyncSwitchCell; using chrome_test_util::TurnSyncSwitchOn; namespace metrics { @@ -353,26 +353,26 @@ [[EarlGrey selectElementWithMatcher:AccountsSyncButton()] performAction:grey_tap()]; // Toggle "Sync Everything" then "History" switches off. - [[EarlGrey selectElementWithMatcher:SyncSwitchCell( + [[EarlGrey selectElementWithMatcher:LegacySyncSwitchCell( l10n_util::GetNSString( IDS_IOS_SYNC_EVERYTHING_TITLE), YES)] performAction:TurnSyncSwitchOn(NO)]; - [[EarlGrey - selectElementWithMatcher:SyncSwitchCell(l10n_util::GetNSString( - IDS_SYNC_DATATYPE_TYPED_URLS), - YES)] + [[EarlGrey selectElementWithMatcher:LegacySyncSwitchCell( + l10n_util::GetNSString( + IDS_SYNC_DATATYPE_TYPED_URLS), + YES)] performAction:TurnSyncSwitchOn(NO)]; AssertUKMEnabled(false); // Toggle "History" then "Sync Everything" switches on. - [[EarlGrey - selectElementWithMatcher:SyncSwitchCell(l10n_util::GetNSString( - IDS_SYNC_DATATYPE_TYPED_URLS), - NO)] + [[EarlGrey selectElementWithMatcher:LegacySyncSwitchCell( + l10n_util::GetNSString( + IDS_SYNC_DATATYPE_TYPED_URLS), + NO)] performAction:TurnSyncSwitchOn(YES)]; - [[EarlGrey selectElementWithMatcher:SyncSwitchCell( + [[EarlGrey selectElementWithMatcher:LegacySyncSwitchCell( l10n_util::GetNSString( IDS_IOS_SYNC_EVERYTHING_TITLE), NO)]
diff --git a/ios/chrome/browser/translate/BUILD.gn b/ios/chrome/browser/translate/BUILD.gn index 9f1d2fd4..2e0a4b1 100644 --- a/ios/chrome/browser/translate/BUILD.gn +++ b/ios/chrome/browser/translate/BUILD.gn
@@ -22,6 +22,8 @@ "translate_infobar_tags.h", "translate_message_infobar_controller.h", "translate_message_infobar_controller.mm", + "translate_option_selection_delegate.h", + "translate_option_selection_handler.h", "translate_ranker_factory.cc", "translate_ranker_factory.h", "translate_ranker_metrics_provider.cc",
diff --git a/ios/chrome/browser/translate/chrome_ios_translate_client.h b/ios/chrome/browser/translate/chrome_ios_translate_client.h index a6ade45..cfba13c 100644 --- a/ios/chrome/browser/translate/chrome_ios_translate_client.h +++ b/ios/chrome/browser/translate/chrome_ios_translate_client.h
@@ -15,7 +15,6 @@ #include "components/translate/core/browser/translate_step.h" #include "components/translate/core/common/translate_errors.h" #include "components/translate/ios/browser/ios_translate_driver.h" -#include "ios/chrome/browser/translate/language_selection_handler.h" #include "ios/web/public/web_state/web_state_observer.h" #include "ios/web/public/web_state/web_state_user_data.h" @@ -37,6 +36,9 @@ class WebState; } // namespace web +@protocol LanguageSelectionHandler; +@protocol TranslateOptionSelectionHandler; + class ChromeIOSTranslateClient : public translate::TranslateClient, public web::WebStateObserver, @@ -79,6 +81,11 @@ language_selection_handler_ = handler; } + void set_translate_option_selection_handler( + id<TranslateOptionSelectionHandler> handler) { + translate_option_selection_handler_ = handler; + } + private: ChromeIOSTranslateClient(web::WebState* web_state); friend class web::WebStateUserData<ChromeIOSTranslateClient>; @@ -94,6 +101,8 @@ std::unique_ptr<translate::TranslateManager> translate_manager_; translate::IOSTranslateDriver translate_driver_; __weak id<LanguageSelectionHandler> language_selection_handler_; + __weak id<TranslateOptionSelectionHandler> + translate_option_selection_handler_; DISALLOW_COPY_AND_ASSIGN(ChromeIOSTranslateClient); };
diff --git a/ios/chrome/browser/translate/chrome_ios_translate_client.mm b/ios/chrome/browser/translate/chrome_ios_translate_client.mm index f9b7dbf..7bb5ada67 100644 --- a/ios/chrome/browser/translate/chrome_ios_translate_client.mm +++ b/ios/chrome/browser/translate/chrome_ios_translate_client.mm
@@ -30,9 +30,11 @@ #include "ios/chrome/browser/pref_names.h" #import "ios/chrome/browser/translate/after_translate_infobar_controller.h" #import "ios/chrome/browser/translate/before_translate_infobar_controller.h" +#import "ios/chrome/browser/translate/language_selection_handler.h" #import "ios/chrome/browser/translate/never_translate_infobar_controller.h" #include "ios/chrome/browser/translate/translate_accept_languages_factory.h" #import "ios/chrome/browser/translate/translate_message_infobar_controller.h" +#import "ios/chrome/browser/translate/translate_option_selection_handler.h" #include "ios/chrome/browser/translate/translate_ranker_factory.h" #include "ios/chrome/browser/translate/translate_service_ios.h" #include "ios/chrome/grit/ios_theme_resources.h" @@ -192,6 +194,7 @@ void ChromeIOSTranslateClient::DidStartLoading(web::WebState* web_state) { [language_selection_handler_ dismissLanguageSelector]; + [translate_option_selection_handler_ dismissTranslateOptionSelector]; } void ChromeIOSTranslateClient::WebStateDestroyed(web::WebState* web_state) { @@ -200,6 +203,7 @@ web_state_ = nullptr; [language_selection_handler_ dismissLanguageSelector]; + [translate_option_selection_handler_ dismissTranslateOptionSelector]; // Translation process can be interrupted. // Destroying the TranslateManager now guarantees that it never has to deal
diff --git a/ios/chrome/browser/translate/language_selection_handler.h b/ios/chrome/browser/translate/language_selection_handler.h index c47bc4f6..d702912a 100644 --- a/ios/chrome/browser/translate/language_selection_handler.h +++ b/ios/chrome/browser/translate/language_selection_handler.h
@@ -14,9 +14,8 @@ // select a language from the languages exposed by a translate_infobar_delegate. @protocol LanguageSelectionHandler -// Tells the handler to display a language selector using the language -// information in |languages| and telling |delegate| the results of the -// selection. +// Tells the handler to display a language selector using the information in +// |context| and telling |delegate| the results of the selection. - (void)showLanguageSelectorWithContext:(LanguageSelectionContext*)context delegate:(id<LanguageSelectionDelegate>)delegate;
diff --git a/ios/chrome/browser/translate/translate_option_selection_delegate.h b/ios/chrome/browser/translate/translate_option_selection_delegate.h new file mode 100644 index 0000000..3f13623 --- /dev/null +++ b/ios/chrome/browser/translate/translate_option_selection_delegate.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 IOS_CHROME_BROWSER_TRANSLATE_TRANSLATE_OPTION_SELECTION_DELEGATE_H_ +#define IOS_CHROME_BROWSER_TRANSLATE_TRANSLATE_OPTION_SELECTION_DELEGATE_H_ + +#import <Foundation/Foundation.h> + +@class PopupMenuPresenter; +@class PopupMenuTableViewController; + +// Protocol adopted by the object receiving user choices of the translate +// options. +@protocol TranslateOptionSelectionDelegate + +// Tells the delegate that the user chose to see the list of target languages. +- (void)popupMenuTableViewControllerDidSelectTargetLanguageSelector: + (PopupMenuTableViewController*)sender; + +// Tells the delegate that the user chose to always translate sites in the +// source language. +- (void)popupMenuTableViewControllerDidSelectAlwaysTranslateSourceLanguage: + (PopupMenuTableViewController*)sender; + +// Tells the delegate that the user chose to never translate sites in the source +// language. +- (void)popupMenuTableViewControllerDidSelectNeverTranslateSourceLanguage: + (PopupMenuTableViewController*)sender; + +// Tells the delegate that the user chose to never translate the current site. +- (void)popupMenuTableViewControllerDidSelectNeverTranslateSite: + (PopupMenuTableViewController*)sender; + +// Tells the delegate that the user chose to see the list of source languages. +- (void)popupMenuTableViewControllerDidSelectSourceLanguageSelector: + (PopupMenuTableViewController*)sender; + +// Tells the delegate that the user chose to close the menu without making a +// selection. +- (void)popupMenuPresenterDidCloseWithoutSelection:(PopupMenuPresenter*)sender; + +@end + +#endif // IOS_CHROME_BROWSER_TRANSLATE_TRANSLATE_OPTION_SELECTION_DELEGATE_H_
diff --git a/ios/chrome/browser/translate/translate_option_selection_handler.h b/ios/chrome/browser/translate/translate_option_selection_handler.h new file mode 100644 index 0000000..1c9ea960 --- /dev/null +++ b/ios/chrome/browser/translate/translate_option_selection_handler.h
@@ -0,0 +1,34 @@ +// 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_TRANSLATE_TRANSLATE_OPTION_SELECTION_HANDLER_H_ +#define IOS_CHROME_BROWSER_TRANSLATE_TRANSLATE_OPTION_SELECTION_HANDLER_H_ + +#import <Foundation/Foundation.h> + +namespace translate { +class TranslateInfoBarDelegate; +} +@protocol TranslateOptionSelectionDelegate; + +// Protocol adopted by an object that can provide an interface for a user to +// select a translate option given by the translate::TranslateInfoBarDelegate. +@protocol TranslateOptionSelectionHandler + +// Tells the handler to display the translate options menu using the information +// in |infobarDelegate| and telling |delegate| the results of the selection. +- (void) + showTranslateOptionSelectorWithInfoBarDelegate: + (const translate::TranslateInfoBarDelegate*)infobarDelegate + delegate: + (id<TranslateOptionSelectionDelegate>) + delegate; + +// Tells the handler to stop displaying the translate options menu and inform +// the delegate no selection was made. +- (void)dismissTranslateOptionSelector; + +@end + +#endif // IOS_CHROME_BROWSER_TRANSLATE_TRANSLATE_OPTION_SELECTION_HANDLER_H_
diff --git a/ios/chrome/browser/ui/BUILD.gn b/ios/chrome/browser/ui/BUILD.gn index 24294363..29c08bc 100644 --- a/ios/chrome/browser/ui/BUILD.gn +++ b/ios/chrome/browser/ui/BUILD.gn
@@ -8,8 +8,6 @@ sources = [ "UIView+SizeClassSupport.h", "UIView+SizeClassSupport.mm", - "background_generator.h", - "background_generator.mm", "chrome_load_params.h", "chrome_load_params.mm", "file_locations.h", @@ -264,13 +262,10 @@ "//base", "//base:i18n", "//components/bookmarks/browser", - "//components/favicon/ios", - "//components/feature_engagement", "//components/image_fetcher/ios", "//components/language/ios/browser", "//components/omnibox/browser", "//components/payments/core", - "//components/prefs", "//components/reading_list/core", "//components/search_engines", "//components/sessions", @@ -286,7 +281,6 @@ "//ios/chrome/browser/bookmarks", "//ios/chrome/browser/browser_state", "//ios/chrome/browser/download", - "//ios/chrome/browser/favicon", "//ios/chrome/browser/feature_engagement", "//ios/chrome/browser/find_in_page", "//ios/chrome/browser/first_run", @@ -382,14 +376,12 @@ "//ios/chrome/browser/web_state_list/web_usage_enabler", "//ios/chrome/browser/webui", "//ios/chrome/common", - "//ios/net", "//ios/public/provider/chrome/browser", "//ios/public/provider/chrome/browser/ui", "//ios/public/provider/chrome/browser/voice", "//ios/third_party/material_components_ios", "//ios/web", "//ios/web/public", - "//net", "//third_party/google_toolbox_for_mac", "//ui/base", "//ui/gfx", @@ -409,11 +401,8 @@ "//ios/chrome/browser/web:web_internal", ] libs = [ - "AssetsLibrary.framework", "MessageUI.framework", - "MobileCoreServices.framework", "Photos.framework", - "QuartzCore.framework", "UIKit.framework", "WebKit.framework", ]
diff --git a/ios/chrome/browser/ui/background_generator.h b/ios/chrome/browser/ui/background_generator.h deleted file mode 100644 index d9e9ad9..0000000 --- a/ios/chrome/browser/ui/background_generator.h +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 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 IOS_CHROME_BROWSER_UI_BACKGROUND_GENERATOR_H_ -#define IOS_CHROME_BROWSER_UI_BACKGROUND_GENERATOR_H_ - -#import <UIKit/UIKit.h> - -// Returns a UIImage of size |backgroundRect| with a radial gradient image at -// |centerPoint| and radiates outwards to a radius of |radius|. The gradient -// starts from |centerColor| at |centerPoint| to |outsideColor| at the end of -// |radius|. |tileImage| is tiled over the entire image and |logoImage| is -// rendered at |centerPoint|. -// |tileImage| and |logoImage| may be nil. -UIImage* GetRadialGradient(CGRect backgroundRect, - CGPoint centerPoint, - CGFloat radius, - CGFloat centerColor, - CGFloat outsideColor, - UIImage* tileImage, - UIImage* logoImage); - -#endif // IOS_CHROME_BROWSER_UI_BACKGROUND_GENERATOR_H_
diff --git a/ios/chrome/browser/ui/background_generator.mm b/ios/chrome/browser/ui/background_generator.mm deleted file mode 100644 index bf4aee3a..0000000 --- a/ios/chrome/browser/ui/background_generator.mm +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 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 "ios/chrome/browser/ui/background_generator.h" - -#import <QuartzCore/QuartzCore.h> -#include <stddef.h> - -#include "base/mac/bundle_locations.h" -#include "base/mac/foundation_util.h" -#include "base/mac/scoped_cftyperef.h" -#import "ios/chrome/browser/ui/util/ui_util.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -// This is a utility function that may be used as a standalone helper function -// to generate a radial gradient UIImage. -UIImage* GetRadialGradient(CGRect backgroundRect, - CGPoint centerPoint, - CGFloat radius, - CGFloat centerColor, - CGFloat outsideColor, - UIImage* tileImage, - UIImage* logoImage) { - UIGraphicsBeginImageContextWithOptions(backgroundRect.size, YES, 0); - CGContextRef context = UIGraphicsGetCurrentContext(); - CGFloat gradient_colors[4] = {centerColor, 1.0, outsideColor, 1.0}; - const size_t kColorCount = 2; - base::ScopedCFTypeRef<CGColorSpaceRef> grey_space( - CGColorSpaceCreateDeviceGray()); - DCHECK_EQ(2u, CGColorSpaceGetNumberOfComponents(grey_space)); - base::ScopedCFTypeRef<CGGradientRef> gradient( - CGGradientCreateWithColorComponents(grey_space, gradient_colors, nullptr, - kColorCount)); - CGContextDrawRadialGradient(context, gradient, centerPoint, 0, centerPoint, - radius, kCGGradientDrawsAfterEndLocation); - if (tileImage) - [tileImage drawAsPatternInRect:backgroundRect]; - if (logoImage) { - CGPoint corner = AlignPointToPixel( - CGPointMake(centerPoint.x - logoImage.size.width / 2.0, - centerPoint.y - logoImage.size.height / 2.0)); - [logoImage drawAtPoint:corner]; - } - UIImage* background = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - return background; -}
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index 1324596..04441e2 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -5,45 +5,26 @@ #import "ios/chrome/browser/ui/browser_view_controller.h" #import "ios/chrome/browser/ui/browser_view_controller+private.h" -#import <AssetsLibrary/AssetsLibrary.h> #import <MessageUI/MessageUI.h> -#import <MobileCoreServices/MobileCoreServices.h> -#import <QuartzCore/QuartzCore.h> - -#include <stdint.h> -#include <cmath> -#include <memory> #include "base/base64.h" #include "base/bind.h" -#include "base/command_line.h" #include "base/feature_list.h" #include "base/files/file_path.h" -#include "base/i18n/rtl.h" #include "base/ios/block_types.h" #include "base/ios/ios_util.h" #include "base/logging.h" #include "base/mac/bundle_locations.h" #include "base/mac/foundation_util.h" -#include "base/macros.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" -#include "base/task/post_task.h" -#include "components/bookmarks/browser/base_bookmark_model_observer.h" -#include "components/bookmarks/browser/bookmark_model.h" -#include "components/favicon/ios/web_favicon_driver.h" -#include "components/feature_engagement/public/event_constants.h" -#include "components/feature_engagement/public/feature_constants.h" -#include "components/feature_engagement/public/tracker.h" #include "components/image_fetcher/ios/ios_image_data_fetcher_wrapper.h" #import "components/language/ios/browser/ios_language_detection_tab_helper.h" #include "components/omnibox/browser/location_bar_model_impl.h" -#include "components/prefs/pref_service.h" #include "components/reading_list/core/reading_list_model.h" -#include "components/search_engines/search_engines_pref_names.h" #include "components/search_engines/template_url_service.h" #include "components/sessions/core/session_types.h" #include "components/sessions/core/tab_restore_service_helper.h" @@ -53,18 +34,11 @@ #include "components/signin/ios/browser/active_state_manager.h" #include "components/strings/grit/components_strings.h" #include "ios/chrome/app/tests_hook.h" -#include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_url_constants.h" -#include "ios/chrome/browser/chrome_url_util.h" #import "ios/chrome/browser/download/download_manager_tab_helper.h" #include "ios/chrome/browser/experimental_flags.h" -#import "ios/chrome/browser/favicon/favicon_loader.h" -#include "ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.h" -#include "ios/chrome/browser/feature_engagement/tracker_factory.h" #include "ios/chrome/browser/feature_engagement/tracker_util.h" -#import "ios/chrome/browser/find_in_page/find_in_page_controller.h" -#import "ios/chrome/browser/find_in_page/find_in_page_model.h" #import "ios/chrome/browser/find_in_page/find_tab_helper.h" #include "ios/chrome/browser/first_run/first_run.h" #import "ios/chrome/browser/geolocation/omnibox_geolocation_controller.h" @@ -88,7 +62,6 @@ #include "ios/chrome/browser/sessions/tab_restore_service_delegate_impl_ios_factory.h" #import "ios/chrome/browser/signin/account_consistency_service_factory.h" #include "ios/chrome/browser/signin/account_reconcilor_factory.h" -#import "ios/chrome/browser/snapshots/snapshot_cache.h" #import "ios/chrome/browser/snapshots/snapshot_generator_delegate.h" #import "ios/chrome/browser/snapshots/snapshot_overlay.h" #import "ios/chrome/browser/snapshots/snapshot_tab_helper.h" @@ -102,20 +75,15 @@ #import "ios/chrome/browser/tabs/tab_private.h" #import "ios/chrome/browser/tabs/tab_util.h" #import "ios/chrome/browser/translate/chrome_ios_translate_client.h" -#import "ios/chrome/browser/translate/language_selection_handler.h" #import "ios/chrome/browser/ui/activity_services/activity_service_legacy_coordinator.h" #import "ios/chrome/browser/ui/activity_services/requirements/activity_service_presentation.h" #import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h" -#import "ios/chrome/browser/ui/autofill/manual_fill/password_coordinator.h" -#import "ios/chrome/browser/ui/background_generator.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.h" -#include "ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.h" #import "ios/chrome/browser/ui/browser_container/browser_container_view_controller.h" #import "ios/chrome/browser/ui/browser_view_controller_dependency_factory.h" #import "ios/chrome/browser/ui/browser_view_controller_helper.h" #import "ios/chrome/browser/ui/bubble/bubble_presenter.h" #import "ios/chrome/browser/ui/bubble/bubble_presenter_delegate.h" -#import "ios/chrome/browser/ui/bubble/bubble_view_controller_presenter.h" #import "ios/chrome/browser/ui/chrome_web_view_factory.h" #import "ios/chrome/browser/ui/commands/application_commands.h" #import "ios/chrome/browser/ui/commands/browser_commands.h" @@ -161,7 +129,6 @@ #import "ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h" #import "ios/chrome/browser/ui/presenters/vertical_animation_container.h" #import "ios/chrome/browser/ui/reading_list/offline_page_native_content.h" -#import "ios/chrome/browser/ui/reading_list/reading_list_menu_notifier.h" #include "ios/chrome/browser/ui/sad_tab/features.h" #import "ios/chrome/browser/ui/sad_tab/sad_tab_coordinator.h" #import "ios/chrome/browser/ui/sad_tab/sad_tab_legacy_coordinator.h" @@ -170,7 +137,6 @@ #import "ios/chrome/browser/ui/static_content/static_html_native_content.h" #import "ios/chrome/browser/ui/tabs/background_tab_animation_view.h" #import "ios/chrome/browser/ui/tabs/foreground_tab_animation_view.h" -#import "ios/chrome/browser/ui/tabs/requirements/tab_strip_constants.h" #import "ios/chrome/browser/ui/tabs/requirements/tab_strip_presentation.h" #import "ios/chrome/browser/ui/tabs/switch_to_tab_animation_view.h" #import "ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.h" @@ -180,7 +146,6 @@ #import "ios/chrome/browser/ui/toolbar/fullscreen/toolbar_ui.h" #import "ios/chrome/browser/ui/toolbar/fullscreen/toolbar_ui_broadcasting_util.h" #import "ios/chrome/browser/ui/toolbar/primary_toolbar_coordinator.h" -#import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/toolbar/public/primary_toolbar_coordinator.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_utils.h" @@ -189,12 +154,10 @@ #import "ios/chrome/browser/ui/toolbar_container/toolbar_container_coordinator.h" #import "ios/chrome/browser/ui/toolbar_container/toolbar_container_features.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" -#include "ios/chrome/browser/ui/util/dynamic_type_util.h" #import "ios/chrome/browser/ui/util/named_guide.h" #import "ios/chrome/browser/ui/util/named_guide_util.h" #import "ios/chrome/browser/ui/util/page_animation_util.h" #import "ios/chrome/browser/ui/util/pasteboard_util.h" -#include "ios/chrome/browser/ui/util/rtl_geometry.h" #include "ios/chrome/browser/ui/util/ui_util.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/browser/ui/voice/text_to_speech_playback_controller.h" @@ -211,16 +174,13 @@ #import "ios/chrome/browser/web/sad_tab_tab_helper.h" #include "ios/chrome/browser/web/web_state_printer.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" -#import "ios/chrome/browser/web_state_list/web_state_opener.h" #import "ios/chrome/browser/web_state_list/web_usage_enabler/web_state_list_web_usage_enabler.h" #import "ios/chrome/browser/web_state_list/web_usage_enabler/web_state_list_web_usage_enabler_factory.h" #import "ios/chrome/browser/webui/net_export_tab_helper.h" #import "ios/chrome/browser/webui/net_export_tab_helper_delegate.h" #import "ios/chrome/browser/webui/show_mail_composer_context.h" #import "ios/chrome/common/ui_util/constraints_ui_util.h" -#include "ios/chrome/grit/ios_chromium_strings.h" #include "ios/chrome/grit/ios_strings.h" -#import "ios/net/request_tracker.h" #include "ios/public/provider/chrome/browser/chrome_browser_provider.h" #include "ios/public/provider/chrome/browser/ui/default_ios_web_view_factory.h" #import "ios/public/provider/chrome/browser/ui/fullscreen_provider.h" @@ -231,7 +191,6 @@ #include "ios/web/public/navigation_item.h" #import "ios/web/public/navigation_manager.h" #include "ios/web/public/referrer_util.h" -#include "ios/web/public/ssl_status.h" #include "ios/web/public/url_scheme_util.h" #include "ios/web/public/user_agent.h" #include "ios/web/public/web_client.h" @@ -244,9 +203,6 @@ #import "ios/web/public/web_state/web_state_delegate_bridge.h" #include "ios/web/public/web_thread.h" #import "ios/web/web_state/ui/crw_web_controller.h" -#import "net/base/mac/url_conversions.h" -#include "net/base/registry_controlled_domains/registry_controlled_domain.h" -#include "net/ssl/ssl_info.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" @@ -506,9 +462,6 @@ // The image fetcher used to save images and perform image-based searches. std::unique_ptr<image_fetcher::IOSImageDataFetcherWrapper> _imageFetcher; - // Cached pointer to the bookmarks model. - bookmarks::BookmarkModel* _bookmarkModel; // weak - // The controller that shows the bookmarking UI after the user taps the star // button. BookmarkInteractionController* _bookmarkInteractionController; @@ -1922,10 +1875,6 @@ self.imageSaver = [[ImageSaver alloc] initWithBaseViewController:self]; self.imageCopier = [[ImageCopier alloc] initWithBaseViewController:self]; - // Register for bookmark changed notification (BookmarkModel may be null - // during testing, so explicitly support this). - _bookmarkModel = ios::BookmarkModelFactory::GetForBrowserState(_browserState); - // Set the TTS playback controller's WebStateList. TextToSpeechPlaybackControllerFactory::GetInstance() ->GetForBrowserState(_browserState)
diff --git a/ios/chrome/browser/ui/settings/cells/BUILD.gn b/ios/chrome/browser/ui/settings/cells/BUILD.gn index d7833bb..28d12eb 100644 --- a/ios/chrome/browser/ui/settings/cells/BUILD.gn +++ b/ios/chrome/browser/ui/settings/cells/BUILD.gn
@@ -38,8 +38,6 @@ "settings_switch_item.mm", "settings_text_item.h", "settings_text_item.mm", - "sync_switch_item.h", - "sync_switch_item.mm", "table_view_clear_browsing_data_item.h", "table_view_clear_browsing_data_item.mm", "text_and_error_item.h", @@ -83,7 +81,6 @@ "import_data_multiline_detail_item_unittest.mm", "passphrase_error_item_unittest.mm", "password_details_item_unittest.mm", - "sync_switch_item_unittest.mm", "text_and_error_item_unittest.mm", "version_item_unittest.mm", ]
diff --git a/ios/chrome/browser/ui/settings/cells/legacy/BUILD.gn b/ios/chrome/browser/ui/settings/cells/legacy/BUILD.gn index f3ccb4f..d0d7b1d 100644 --- a/ios/chrome/browser/ui/settings/cells/legacy/BUILD.gn +++ b/ios/chrome/browser/ui/settings/cells/legacy/BUILD.gn
@@ -10,6 +10,8 @@ "legacy_settings_detail_item.mm", "legacy_settings_switch_item.h", "legacy_settings_switch_item.mm", + "legacy_sync_switch_item.h", + "legacy_sync_switch_item.mm", ] deps = [ @@ -30,6 +32,7 @@ testonly = true sources = [ "legacy_autofill_data_item_unittest.mm", + "legacy_sync_switch_item_unittest.mm", ] deps = [
diff --git a/ios/chrome/browser/ui/settings/cells/sync_switch_item.h b/ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.h similarity index 80% rename from ios/chrome/browser/ui/settings/cells/sync_switch_item.h rename to ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.h index 224ebfe0..8998695 100644 --- a/ios/chrome/browser/ui/settings/cells/sync_switch_item.h +++ b/ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.h
@@ -2,15 +2,15 @@ // 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_SETTINGS_CELLS_SYNC_SWITCH_ITEM_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_SYNC_SWITCH_ITEM_H_ +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_LEGACY_LEGACY_SYNC_SWITCH_ITEM_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_LEGACY_LEGACY_SYNC_SWITCH_ITEM_H_ #import <UIKit/UIKit.h> #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h" #import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h" -@interface SyncSwitchItem : CollectionViewItem +@interface LegacySyncSwitchItem : CollectionViewItem // The title text to display. @property(nonatomic, copy) NSString* text; @@ -34,7 +34,7 @@ @end // Cell representation for AccountSignInItem. -@interface SyncSwitchCell : MDCCollectionViewCell +@interface LegacySyncSwitchCell : MDCCollectionViewCell // Cell title. @property(nonatomic, readonly, strong) UILabel* textLabel; @@ -50,4 +50,4 @@ @end -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_SYNC_SWITCH_ITEM_H_ +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_LEGACY_LEGACY_SYNC_SWITCH_ITEM_H_
diff --git a/ios/chrome/browser/ui/settings/cells/sync_switch_item.mm b/ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.mm similarity index 94% rename from ios/chrome/browser/ui/settings/cells/sync_switch_item.mm rename to ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.mm index 0cd339f..55cc8f6e 100644 --- a/ios/chrome/browser/ui/settings/cells/sync_switch_item.mm +++ b/ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.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/ui/settings/cells/sync_switch_item.h" +#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.h" #include "ios/chrome/browser/ui/collection_view/cells/collection_view_cell_constants.h" #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h" @@ -28,9 +28,9 @@ const CGFloat kHorizontalSwitchPadding = 10; } // namespace -#pragma mark - SyncSwitchItem +#pragma mark - LegacySyncSwitchItem -@implementation SyncSwitchItem +@implementation LegacySyncSwitchItem @synthesize text = _text; @synthesize detailText = _detailText; @@ -42,20 +42,20 @@ - (instancetype)initWithType:(NSInteger)type { self = [super initWithType:type]; if (self) { - self.cellClass = [SyncSwitchCell class]; + self.cellClass = [LegacySyncSwitchCell class]; self.enabled = YES; } return self; } -- (void)configureCell:(SyncSwitchCell*)cell { +- (void)configureCell:(LegacySyncSwitchCell*)cell { [super configureCell:cell]; cell.textLabel.text = self.text; cell.detailTextLabel.text = self.detailText; cell.switchView.enabled = self.isEnabled; cell.switchView.on = self.isOn; cell.textLabel.textColor = - [SyncSwitchCell defaultTextColorForState:cell.switchView.state]; + [LegacySyncSwitchCell defaultTextColorForState:cell.switchView.state]; if (self.isEnabled) { cell.textLabel.textColor = [[MDCPalette greyPalette] tint900]; cell.switchView.enabled = YES; @@ -69,7 +69,7 @@ @end -@implementation SyncSwitchCell +@implementation LegacySyncSwitchCell @synthesize textLabel = _textLabel; @synthesize detailTextLabel = _detailTextLabel;
diff --git a/ios/chrome/browser/ui/settings/cells/sync_switch_item_unittest.mm b/ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item_unittest.mm similarity index 73% rename from ios/chrome/browser/ui/settings/cells/sync_switch_item_unittest.mm rename to ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item_unittest.mm index ec5b2b2..a162162 100644 --- a/ios/chrome/browser/ui/settings/cells/sync_switch_item_unittest.mm +++ b/ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item_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/ui/settings/cells/sync_switch_item.h" +#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.h" #include "testing/gtest/include/gtest/gtest.h" #import "testing/gtest_mac.h" @@ -14,14 +14,14 @@ namespace { -using SyncSwitchItemTest = PlatformTest; +using LegacySyncSwitchItemTest = PlatformTest; // Tests that the text label and showing status are set properly after a call to // |configureCell:|. -TEST_F(SyncSwitchItemTest, ConfigureCell) { - SyncSwitchItem* item = [[SyncSwitchItem alloc] initWithType:0]; - SyncSwitchCell* cell = [[[item cellClass] alloc] init]; - EXPECT_TRUE([cell isMemberOfClass:[SyncSwitchCell class]]); +TEST_F(LegacySyncSwitchItemTest, ConfigureCell) { + LegacySyncSwitchItem* item = [[LegacySyncSwitchItem alloc] initWithType:0]; + LegacySyncSwitchCell* cell = [[[item cellClass] alloc] init]; + EXPECT_TRUE([cell isMemberOfClass:[LegacySyncSwitchCell class]]); EXPECT_NSEQ(nil, cell.textLabel.text); NSString* text = @"Test Switch"; @@ -45,16 +45,16 @@ // Tests that the text color and enabled state of the switch are set correctly // by a call to |configureCell:|. -TEST_F(SyncSwitchItemTest, EnabledAndDisabled) { - SyncSwitchCell* cell = [[SyncSwitchCell alloc] init]; - SyncSwitchItem* item = [[SyncSwitchItem alloc] initWithType:0]; +TEST_F(LegacySyncSwitchItemTest, EnabledAndDisabled) { + LegacySyncSwitchCell* cell = [[LegacySyncSwitchCell alloc] init]; + LegacySyncSwitchItem* item = [[LegacySyncSwitchItem alloc] initWithType:0]; item.text = @"Test Switch"; // Text color possibilities. UIColor* enabledColor = - [SyncSwitchCell defaultTextColorForState:UIControlStateNormal]; + [LegacySyncSwitchCell defaultTextColorForState:UIControlStateNormal]; UIColor* disabledColor = - [SyncSwitchCell defaultTextColorForState:UIControlStateDisabled]; + [LegacySyncSwitchCell defaultTextColorForState:UIControlStateDisabled]; // Enabled and off. item.on = NO; @@ -85,8 +85,8 @@ EXPECT_NSEQ(disabledColor, cell.textLabel.textColor); } -TEST_F(SyncSwitchItemTest, PrepareForReuseClearsActions) { - SyncSwitchCell* cell = [[SyncSwitchCell alloc] init]; +TEST_F(LegacySyncSwitchItemTest, PrepareForReuseClearsActions) { + LegacySyncSwitchCell* cell = [[LegacySyncSwitchCell alloc] init]; UISwitch* switchView = cell.switchView; NSArray* target = [NSArray array];
diff --git a/ios/chrome/browser/ui/settings/google_services_settings_mediator.mm b/ios/chrome/browser/ui/settings/google_services_settings_mediator.mm index 341ef0fa..9f21238a 100644 --- a/ios/chrome/browser/ui/settings/google_services_settings_mediator.mm +++ b/ios/chrome/browser/ui/settings/google_services_settings_mediator.mm
@@ -21,8 +21,8 @@ #include "ios/chrome/browser/sync/sync_setup_service.h" #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h" #import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h" +#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.h" -#import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h" #import "ios/chrome/browser/ui/settings/sync_utils/sync_util.h" #import "ios/chrome/browser/ui/settings/utils/observable_boolean.h" #import "ios/chrome/browser/ui/settings/utils/pref_backed_boolean.h" @@ -123,11 +123,12 @@ // Item to display the sync error. @property(nonatomic, strong) SettingsImageDetailTextItem* syncErrorItem; // Item for "Sync Everything" section. -@property(nonatomic, strong, readonly) SyncSwitchItem* syncEverythingItem; +@property(nonatomic, strong, readonly) LegacySyncSwitchItem* syncEverythingItem; // All the items for the personalized section. @property(nonatomic, strong, readonly) ItemArray personalizedItems; // Item for the autocomplete wallet feature. -@property(nonatomic, strong, readonly) SyncSwitchItem* autocompleteWalletItem; +@property(nonatomic, strong, readonly) + LegacySyncSwitchItem* autocompleteWalletItem; // All the items for the non-personalized section. @property(nonatomic, strong, readonly) ItemArray nonPersonalizedItems; @@ -274,43 +275,43 @@ - (ItemArray)personalizedItems { if (!_personalizedItems) { - SyncSwitchItem* syncBookmarksItem = [self + LegacySyncSwitchItem* syncBookmarksItem = [self switchItemWithItemType:SyncBookmarksItemType textStringID:IDS_IOS_GOOGLE_SERVICES_SETTINGS_BOOKMARKS_TEXT detailStringID:0 commandID:GoogleServicesSettingsCommandIDToggleDataTypeSync dataType:SyncSetupService::kSyncBookmarks]; - SyncSwitchItem* syncHistoryItem = [self + LegacySyncSwitchItem* syncHistoryItem = [self switchItemWithItemType:SyncHistoryItemType textStringID:IDS_IOS_GOOGLE_SERVICES_SETTINGS_HISTORY_TEXT detailStringID:0 commandID:GoogleServicesSettingsCommandIDToggleDataTypeSync dataType:SyncSetupService::kSyncOmniboxHistory]; - SyncSwitchItem* syncPasswordsItem = [self + LegacySyncSwitchItem* syncPasswordsItem = [self switchItemWithItemType:SyncPasswordsItemType textStringID:IDS_IOS_GOOGLE_SERVICES_SETTINGS_PASSWORD_TEXT detailStringID:0 commandID:GoogleServicesSettingsCommandIDToggleDataTypeSync dataType:SyncSetupService::kSyncPasswords]; - SyncSwitchItem* syncOpenTabsItem = [self + LegacySyncSwitchItem* syncOpenTabsItem = [self switchItemWithItemType:SyncOpenTabsItemType textStringID:IDS_IOS_GOOGLE_SERVICES_SETTINGS_OPENTABS_TEXT detailStringID:0 commandID:GoogleServicesSettingsCommandIDToggleDataTypeSync dataType:SyncSetupService::kSyncOpenTabs]; - SyncSwitchItem* syncAutofillItem = [self + LegacySyncSwitchItem* syncAutofillItem = [self switchItemWithItemType:SyncAutofillItemType textStringID:IDS_IOS_GOOGLE_SERVICES_SETTINGS_AUTOFILL_TEXT detailStringID:0 commandID:GoogleServicesSettingsCommandIDToggleDataTypeSync dataType:SyncSetupService::kSyncAutofill]; - SyncSwitchItem* syncSettingsItem = [self + LegacySyncSwitchItem* syncSettingsItem = [self switchItemWithItemType:SyncAutofillItemType textStringID:IDS_IOS_GOOGLE_SERVICES_SETTINGS_SETTINGS_TEXT detailStringID:0 commandID:GoogleServicesSettingsCommandIDToggleDataTypeSync dataType:SyncSetupService::kSyncPreferences]; - SyncSwitchItem* syncReadingListItem = [self + LegacySyncSwitchItem* syncReadingListItem = [self switchItemWithItemType:SyncReadingListItemType textStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_READING_LIST_TEXT @@ -351,7 +352,7 @@ return _personalizedItems; } -- (SyncSwitchItem*)autocompleteWalletItem { +- (LegacySyncSwitchItem*)autocompleteWalletItem { if (!_autocompleteWalletItem) { _autocompleteWalletItem = [self switchItemWithItemType:AutocompleteWalletItemType @@ -367,7 +368,7 @@ - (ItemArray)nonPersonalizedItems { if (!_nonPersonalizedItems) { - SyncSwitchItem* autocompleteSearchesAndURLsItem = [self + LegacySyncSwitchItem* autocompleteSearchesAndURLsItem = [self switchItemWithItemType:AutocompleteSearchesAndURLsItemType textStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_AUTOCOMPLETE_SEARCHES_AND_URLS_TEXT @@ -376,7 +377,7 @@ commandID: GoogleServicesSettingsCommandIDToggleAutocompleteSearchesService dataType:0]; - SyncSwitchItem* preloadPagesItem = [self + LegacySyncSwitchItem* preloadPagesItem = [self switchItemWithItemType:PreloadPagesItemType textStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_PRELOAD_PAGES_TEXT @@ -385,7 +386,7 @@ commandID: GoogleServicesSettingsCommandIDTogglePreloadPagesService dataType:0]; - SyncSwitchItem* improveChromeItem = [self + LegacySyncSwitchItem* improveChromeItem = [self switchItemWithItemType:ImproveChromeItemType textStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_IMPROVE_CHROME_TEXT @@ -394,7 +395,7 @@ commandID: GoogleServicesSettingsCommandIDToggleImproveChromeService dataType:0]; - SyncSwitchItem* betterSearchAndBrowsingItemType = [self + LegacySyncSwitchItem* betterSearchAndBrowsingItemType = [self switchItemWithItemType:BetterSearchAndBrowsingItemType textStringID: IDS_IOS_GOOGLE_SERVICES_SETTINGS_BETTER_SEARCH_AND_BROWSING_TEXT @@ -413,13 +414,14 @@ #pragma mark - Private -// Creates a SyncSwitchItem instance. -- (SyncSwitchItem*)switchItemWithItemType:(NSInteger)itemType - textStringID:(int)textStringID - detailStringID:(int)detailStringID - commandID:(NSInteger)commandID - dataType:(NSInteger)dataType { - SyncSwitchItem* switchItem = [[SyncSwitchItem alloc] initWithType:itemType]; +// Creates a LegacySyncSwitchItem instance. +- (LegacySyncSwitchItem*)switchItemWithItemType:(NSInteger)itemType + textStringID:(int)textStringID + detailStringID:(int)detailStringID + commandID:(NSInteger)commandID + dataType:(NSInteger)dataType { + LegacySyncSwitchItem* switchItem = + [[LegacySyncSwitchItem alloc] initWithType:itemType]; switchItem.text = GetNSString(textStringID); if (detailStringID) switchItem.detailText = GetNSString(detailStringID); @@ -537,8 +539,9 @@ switchItemEnabled:(BOOL)switchItemEnabled textItemEnabled:(BOOL)textItemEnabled { for (CollectionViewItem* item in items) { - if ([item isKindOfClass:[SyncSwitchItem class]]) { - SyncSwitchItem* switchItem = base::mac::ObjCCast<SyncSwitchItem>(item); + if ([item isKindOfClass:[LegacySyncSwitchItem class]]) { + LegacySyncSwitchItem* switchItem = + base::mac::ObjCCast<LegacySyncSwitchItem>(item); switch (switchItem.commandID) { case GoogleServicesSettingsCommandIDToggleDataTypeSync: { SyncSetupService::SyncableDatatype dataType =
diff --git a/ios/chrome/browser/ui/settings/google_services_settings_view_controller.mm b/ios/chrome/browser/ui/settings/google_services_settings_view_controller.mm index 0354f5a..0189159 100644 --- a/ios/chrome/browser/ui/settings/google_services_settings_view_controller.mm +++ b/ios/chrome/browser/ui/settings/google_services_settings_view_controller.mm
@@ -8,8 +8,8 @@ #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h" #import "ios/chrome/browser/ui/collection_view/cells/collection_view_switch_item.h" #import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h" +#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.h" -#import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h" #import "ios/chrome/browser/ui/settings/google_services_settings_local_commands.h" #import "ios/chrome/browser/ui/settings/google_services_settings_service_delegate.h" #import "ios/chrome/browser/ui/settings/google_services_settings_view_controller_model_delegate.h" @@ -60,8 +60,9 @@ - (void)switchAction:(UISwitch*)sender { NSIndexPath* indexPath = [self indexPathForTag:sender.tag]; - SyncSwitchItem* syncSwitchItem = base::mac::ObjCCastStrict<SyncSwitchItem>( - [self.collectionViewModel itemAtIndexPath:indexPath]); + LegacySyncSwitchItem* syncSwitchItem = + base::mac::ObjCCastStrict<LegacySyncSwitchItem>( + [self.collectionViewModel itemAtIndexPath:indexPath]); BOOL isOn = sender.isOn; GoogleServicesSettingsCommandID commandID = static_cast<GoogleServicesSettingsCommandID>(syncSwitchItem.commandID); @@ -107,9 +108,9 @@ cellForItemAtIndexPath:(NSIndexPath*)indexPath { UICollectionViewCell* cell = [super collectionView:collectionView cellForItemAtIndexPath:indexPath]; - if ([cell isKindOfClass:[SyncSwitchCell class]]) { - SyncSwitchCell* switchCell = - base::mac::ObjCCastStrict<SyncSwitchCell>(cell); + if ([cell isKindOfClass:[LegacySyncSwitchCell class]]) { + LegacySyncSwitchCell* switchCell = + base::mac::ObjCCastStrict<LegacySyncSwitchCell>(cell); [switchCell.switchView addTarget:self action:@selector(switchAction:) forControlEvents:UIControlEventValueChanged]; @@ -197,7 +198,7 @@ shouldHighlightItemAtIndexPath:indexPath]; CollectionViewItem* item = [self.collectionViewModel itemAtIndexPath:indexPath]; - if ([item isKindOfClass:[SyncSwitchItem class]]) { + if ([item isKindOfClass:[LegacySyncSwitchItem class]]) { return NO; } else if ([item isKindOfClass:[SettingsImageDetailTextItem class]]) { return YES;
diff --git a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm index 5db2939..2cc3374 100644 --- a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm +++ b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
@@ -37,12 +37,12 @@ #import "ios/chrome/browser/ui/settings/cells/legacy/legacy_autofill_data_item.h" #import "ios/chrome/browser/ui/settings/cells/legacy/legacy_settings_detail_item.h" #import "ios/chrome/browser/ui/settings/cells/legacy/legacy_settings_switch_item.h" +#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.h" #import "ios/chrome/browser/ui/settings/cells/passphrase_error_item.h" #import "ios/chrome/browser/ui/settings/cells/password_details_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_search_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_text_item.h" -#import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h" #import "ios/chrome/browser/ui/settings/cells/text_and_error_item.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/public/provider/chrome/browser/chrome_browser_provider.h" @@ -621,8 +621,8 @@ } - (CollectionViewItem*)syncSwitchItem { - SyncSwitchItem* item = - [[SyncSwitchItem alloc] initWithType:ItemTypeSwitchSync]; + LegacySyncSwitchItem* item = + [[LegacySyncSwitchItem alloc] initWithType:ItemTypeSwitchSync]; item.text = @"Cell used in Sync Settings"; item.detailText = @"This is a very long text that is intended to overflow to two lines.";
diff --git a/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller.mm b/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller.mm index eab0fb2..b9920901 100644 --- a/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller.mm +++ b/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller.mm
@@ -39,8 +39,8 @@ #import "ios/chrome/browser/ui/commands/open_new_tab_command.h" #import "ios/chrome/browser/ui/commands/show_signin_command.h" #import "ios/chrome/browser/ui/settings/cells/legacy/legacy_settings_detail_item.h" +#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_text_item.h" -#import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h" #import "ios/chrome/browser/ui/settings/cells/text_and_error_item.h" #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" #import "ios/chrome/browser/ui/settings/sync_encryption_passphrase_table_view_controller.h" @@ -350,7 +350,7 @@ #pragma mark - Model items - (CollectionViewItem*)syncSwitchItem:(BOOL)isOn { - SyncSwitchItem* syncSwitchItem = [self + LegacySyncSwitchItem* syncSwitchItem = [self switchItemWithType:ItemTypeSyncSwitch title:l10n_util::GetNSString(IDS_IOS_SYNC_SETTING_TITLE) subTitle:l10n_util::GetNSString( @@ -387,7 +387,7 @@ } - (CollectionViewItem*)syncEverythingSwitchItem:(BOOL)isOn { - SyncSwitchItem* syncSwitchItem = [self + LegacySyncSwitchItem* syncSwitchItem = [self switchItemWithType:ItemTypeSyncEverything title:l10n_util::GetNSString(IDS_IOS_SYNC_EVERYTHING_TITLE) subTitle:nil]; @@ -401,7 +401,7 @@ syncer::ModelType modelType = _syncSetupService->GetModelType(dataType); BOOL isOn = _syncSetupService->IsDataTypePreferred(modelType); - SyncSwitchItem* syncDataTypeItem = + LegacySyncSwitchItem* syncDataTypeItem = [self switchItemWithType:ItemTypeSyncableDataType title:l10n_util::GetNSString( [self titleIdForSyncableDataType:dataType]) @@ -415,7 +415,7 @@ - (CollectionViewItem*)switchItemForAutofillWalletImport { NSString* title = l10n_util::GetNSString( IDS_AUTOFILL_ENABLE_PAYMENTS_INTEGRATION_CHECKBOX_LABEL); - SyncSwitchItem* autofillWalletImportItem = + LegacySyncSwitchItem* autofillWalletImportItem = [self switchItemWithType:ItemTypeAutofillWalletImport title:title subTitle:nil]; @@ -447,10 +447,11 @@ #pragma mark Item Constructors -- (SyncSwitchItem*)switchItemWithType:(NSInteger)type - title:(NSString*)title - subTitle:(NSString*)detailText { - SyncSwitchItem* switchItem = [[SyncSwitchItem alloc] initWithType:type]; +- (LegacySyncSwitchItem*)switchItemWithType:(NSInteger)type + title:(NSString*)title + subTitle:(NSString*)detailText { + LegacySyncSwitchItem* switchItem = + [[LegacySyncSwitchItem alloc] initWithType:type]; switchItem.text = title; switchItem.detailText = detailText; return switchItem; @@ -474,16 +475,16 @@ break; } case ItemTypeSyncSwitch: { - SyncSwitchCell* switchCell = - base::mac::ObjCCastStrict<SyncSwitchCell>(cell); + LegacySyncSwitchCell* switchCell = + base::mac::ObjCCastStrict<LegacySyncSwitchCell>(cell); [switchCell.switchView addTarget:self action:@selector(changeSyncStatusToOn:) forControlEvents:UIControlEventValueChanged]; break; } case ItemTypeSyncEverything: { - SyncSwitchCell* switchCell = - base::mac::ObjCCastStrict<SyncSwitchCell>(cell); + LegacySyncSwitchCell* switchCell = + base::mac::ObjCCastStrict<LegacySyncSwitchCell>(cell); [switchCell.switchView addTarget:self action:@selector(changeSyncEverythingStatusToOn:) @@ -491,8 +492,8 @@ break; } case ItemTypeSyncableDataType: { - SyncSwitchCell* switchCell = - base::mac::ObjCCastStrict<SyncSwitchCell>(cell); + LegacySyncSwitchCell* switchCell = + base::mac::ObjCCastStrict<LegacySyncSwitchCell>(cell); [switchCell.switchView addTarget:self action:@selector(changeDataTypeSyncStatusToOn:) forControlEvents:UIControlEventValueChanged]; @@ -500,8 +501,8 @@ break; } case ItemTypeAutofillWalletImport: { - SyncSwitchCell* switchCell = - base::mac::ObjCCastStrict<SyncSwitchCell>(cell); + LegacySyncSwitchCell* switchCell = + base::mac::ObjCCastStrict<LegacySyncSwitchCell>(cell); [switchCell.switchView addTarget:self action:@selector(autofillWalletImportChanged:) forControlEvents:UIControlEventValueChanged]; @@ -613,8 +614,9 @@ indexPathForItemType:ItemTypeSyncSwitch sectionIdentifier:SectionIdentifierEnableSync]; - SyncSwitchItem* item = base::mac::ObjCCastStrict<SyncSwitchItem>( - [self.collectionViewModel itemAtIndexPath:indexPath]); + LegacySyncSwitchItem* item = + base::mac::ObjCCastStrict<LegacySyncSwitchItem>( + [self.collectionViewModel itemAtIndexPath:indexPath]); item.on = isNowOn; } [self updateCollectionView]; @@ -715,8 +717,9 @@ NSIndexPath* indexPath = [self.collectionViewModel indexPathForItemType:ItemTypeSyncEverything sectionIdentifier:SectionIdentifierSyncServices]; - SyncSwitchItem* item = base::mac::ObjCCastStrict<SyncSwitchItem>( - [self.collectionViewModel itemAtIndexPath:indexPath]); + LegacySyncSwitchItem* item = + base::mac::ObjCCastStrict<LegacySyncSwitchItem>( + [self.collectionViewModel itemAtIndexPath:indexPath]); item.on = isNowOn; } [self updateCollectionView]; @@ -730,8 +733,8 @@ BOOL isOn = sender.isOn; - SyncSwitchItem* syncSwitchItem = - base::mac::ObjCCastStrict<SyncSwitchItem>([self.collectionViewModel + LegacySyncSwitchItem* syncSwitchItem = + base::mac::ObjCCastStrict<LegacySyncSwitchItem>([self.collectionViewModel itemAtIndexPath:[self indexPathForTag:sender.tag]]); SyncSetupService::SyncableDatatype dataType = (SyncSetupService::SyncableDatatype)syncSwitchItem.dataType; @@ -791,8 +794,9 @@ indexPathForItemType:ItemTypeSyncSwitch sectionIdentifier:SectionIdentifierEnableSync]; - SyncSwitchItem* syncItem = base::mac::ObjCCastStrict<SyncSwitchItem>( - [self.collectionViewModel itemAtIndexPath:indexPath]); + LegacySyncSwitchItem* syncItem = + base::mac::ObjCCastStrict<LegacySyncSwitchItem>( + [self.collectionViewModel itemAtIndexPath:indexPath]); syncItem.on = _syncSetupService->IsSyncEnabled(); [self reconfigureCellsForItems:@[ syncItem ]]; @@ -821,8 +825,8 @@ indexPath = [self.collectionViewModel indexPathForItemType:ItemTypeSyncEverything sectionIdentifier:SectionIdentifierSyncServices]; - SyncSwitchItem* syncEverythingItem = - base::mac::ObjCCastStrict<SyncSwitchItem>( + LegacySyncSwitchItem* syncEverythingItem = + base::mac::ObjCCastStrict<LegacySyncSwitchItem>( [self.collectionViewModel itemAtIndexPath:indexPath]); syncEverythingItem.on = _syncSetupService->IsSyncingAllDataTypes(); syncEverythingItem.enabled = [self shouldSyncEverythingItemBeEnabled]; @@ -838,8 +842,9 @@ indexPathForItemType:ItemTypeSyncableDataType sectionIdentifier:SectionIdentifierSyncServices atIndex:index]; - SyncSwitchItem* syncSwitchItem = base::mac::ObjCCastStrict<SyncSwitchItem>( - [self.collectionViewModel itemAtIndexPath:indexPath]); + LegacySyncSwitchItem* syncSwitchItem = + base::mac::ObjCCastStrict<LegacySyncSwitchItem>( + [self.collectionViewModel itemAtIndexPath:indexPath]); DCHECK_EQ(index, syncSwitchItem.dataType); syncer::ModelType modelType = _syncSetupService->GetModelType(dataType); syncSwitchItem.on = _syncSetupService->IsDataTypePreferred(modelType); @@ -893,8 +898,9 @@ NSIndexPath* indexPath = [self.collectionViewModel indexPathForItemType:ItemTypeAutofillWalletImport sectionIdentifier:SectionIdentifierSyncServices]; - SyncSwitchItem* syncSwitchItem = base::mac::ObjCCastStrict<SyncSwitchItem>( - [self.collectionViewModel itemAtIndexPath:indexPath]); + LegacySyncSwitchItem* syncSwitchItem = + base::mac::ObjCCastStrict<LegacySyncSwitchItem>( + [self.collectionViewModel itemAtIndexPath:indexPath]); syncSwitchItem.on = [self isAutofillWalletImportOn]; syncSwitchItem.enabled = [self isAutofillWalletImportItemEnabled]; [self reconfigureCellsForItems:@[ syncSwitchItem ]];
diff --git a/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller_unittest.mm index 820faf4..5fae263 100644 --- a/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller_unittest.mm
@@ -27,7 +27,7 @@ #include "ios/chrome/browser/sync/sync_setup_service_mock.h" #import "ios/chrome/browser/ui/collection_view/collection_view_controller_test.h" #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" -#import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h" +#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.h" #import "ios/chrome/browser/ui/settings/cells/text_and_error_item.h" #import "ios/chrome/browser/ui/settings/sync_utils/sync_util.h" #include "ios/chrome/grit/ios_strings.h" @@ -249,7 +249,7 @@ EXPECT_EQ(expected_number_of_items, NumberOfItemsInSection(1)); EXPECT_EQ(2, NumberOfItemsInSection(2)); - SyncSwitchItem* syncItem = GetCollectionViewItem(0, 0); + LegacySyncSwitchItem* syncItem = GetCollectionViewItem(0, 0); EXPECT_EQ(syncItem.isOn, YES); EXPECT_NSEQ(syncItem.text, l10n_util::GetNSString(IDS_IOS_SYNC_SETTING_TITLE)); @@ -257,7 +257,7 @@ syncItem.detailText, l10n_util::GetNSString(IDS_IOS_SIGN_IN_TO_CHROME_SETTING_SUBTITLE)); - SyncSwitchItem* syncEverythingItem = GetCollectionViewItem(1, 0); + LegacySyncSwitchItem* syncEverythingItem = GetCollectionViewItem(1, 0); EXPECT_EQ(syncEverythingItem.isOn, YES); EXPECT_NSEQ(syncEverythingItem.text, l10n_util::GetNSString(IDS_IOS_SYNC_EVERYTHING_TITLE)); @@ -266,13 +266,14 @@ for (int i = 0; i < SyncSetupService::kNumberOfSyncableDatatypes; i++) { SyncSetupService::SyncableDatatype dataType = static_cast<SyncSetupService::SyncableDatatype>(i); - SyncSwitchItem* syncDataTypeItem = GetCollectionViewItem(1, item++); + LegacySyncSwitchItem* syncDataTypeItem = GetCollectionViewItem(1, item++); EXPECT_NSEQ(syncDataTypeItem.text, l10n_util::GetNSString( [sync_controller titleIdForSyncableDataType:dataType])); } - SyncSwitchItem* autofillWalletImportItem = GetCollectionViewItem(1, item); + LegacySyncSwitchItem* autofillWalletImportItem = + GetCollectionViewItem(1, item); NSString* title = l10n_util::GetNSString( IDS_AUTOFILL_ENABLE_PAYMENTS_INTEGRATION_CHECKBOX_LABEL); EXPECT_NSEQ(autofillWalletImportItem.text, title); @@ -287,7 +288,7 @@ CreateSyncController(); for (int item = 0; item < NumberOfItemsInSection(1); ++item) { - SyncSwitchItem* object = GetCollectionViewItem(1, item); + LegacySyncSwitchItem* object = GetCollectionViewItem(1, item); EXPECT_FALSE(object.enabled); } @@ -301,15 +302,15 @@ TurnSyncEverythingOn(); CreateSyncController(); - SyncSwitchItem* syncEverythingItem = GetCollectionViewItem(1, 0); + LegacySyncSwitchItem* syncEverythingItem = GetCollectionViewItem(1, 0); EXPECT_TRUE(syncEverythingItem.enabled); for (int item = 1; item <= SyncSetupService::kNumberOfSyncableDatatypes; ++item) { - SyncSwitchItem* object = GetCollectionViewItem(1, item); + LegacySyncSwitchItem* object = GetCollectionViewItem(1, item); EXPECT_FALSE(object.enabled); } - SyncSwitchItem* autofillWalletImportItem = + LegacySyncSwitchItem* autofillWalletImportItem = GetCollectionViewItem(1, NumberOfItemsInSection(1) - 1); EXPECT_FALSE(autofillWalletImportItem.enabled); @@ -325,7 +326,7 @@ TurnSyncEverythingOn(); CreateSyncController(); - SyncSwitchItem* autofillWalletImportItem = + LegacySyncSwitchItem* autofillWalletImportItem = GetCollectionViewItem(1, NumberOfItemsInSection(1) - 1); EXPECT_FALSE(autofillWalletImportItem.isOn); } @@ -338,7 +339,7 @@ TurnSyncEverythingOn(); CreateSyncController(); - SyncSwitchItem* autofillWalletImportItem = + LegacySyncSwitchItem* autofillWalletImportItem = GetCollectionViewItem(1, NumberOfItemsInSection(1) - 1); EXPECT_TRUE(autofillWalletImportItem.isOn); }
diff --git a/ios/chrome/browser/ui/side_swipe/card_side_swipe_view.mm b/ios/chrome/browser/ui/side_swipe/card_side_swipe_view.mm index b88881b..277c4a9 100644 --- a/ios/chrome/browser/ui/side_swipe/card_side_swipe_view.mm +++ b/ios/chrome/browser/ui/side_swipe/card_side_swipe_view.mm
@@ -13,7 +13,6 @@ #import "ios/chrome/browser/snapshots/snapshot_tab_helper.h" #import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab_model.h" -#import "ios/chrome/browser/ui/background_generator.h" #import "ios/chrome/browser/ui/side_swipe/side_swipe_util.h" #import "ios/chrome/browser/ui/side_swipe/swipe_view.h" #import "ios/chrome/browser/ui/side_swipe_gesture_recognizer.h"
diff --git a/ios/chrome/test/earl_grey/chrome_actions.mm b/ios/chrome/test/earl_grey/chrome_actions.mm index f466157..3ca9734 100644 --- a/ios/chrome/test/earl_grey/chrome_actions.mm +++ b/ios/chrome/test/earl_grey/chrome_actions.mm
@@ -7,8 +7,8 @@ #import "base/mac/foundation_util.h" #import "ios/chrome/browser/ui/collection_view/cells/collection_view_switch_item.h" #import "ios/chrome/browser/ui/settings/cells/legacy/legacy_settings_switch_item.h" +#import "ios/chrome/browser/ui/settings/cells/legacy/legacy_sync_switch_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_switch_item.h" -#import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h" #import "ios/chrome/test/app/chrome_test_util.h" #import "ios/web/public/test/earl_grey/web_view_actions.h" @@ -106,8 +106,8 @@ constraints:constraints performBlock:^BOOL(id sync_switch_cell, __strong NSError** error_or_nil) { - SyncSwitchCell* switch_cell = - base::mac::ObjCCastStrict<SyncSwitchCell>(sync_switch_cell); + LegacySyncSwitchCell* switch_cell = + base::mac::ObjCCastStrict<LegacySyncSwitchCell>(sync_switch_cell); UISwitch* switch_view = switch_cell.switchView; if (switch_view.on != on) { id<GREYAction> long_press_action = [GREYActions
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.h b/ios/chrome/test/earl_grey/chrome_matchers.h index f97e047..f7282c9 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers.h +++ b/ios/chrome/test/earl_grey/chrome_matchers.h
@@ -109,8 +109,9 @@ BOOL is_toggled_on, BOOL is_enabled); -// Matcher for SyncSwitchCell. -id<GREYMatcher> SyncSwitchCell(NSString* accessibilityLabel, BOOL isToggledOn); +// Matcher for LegacySyncSwitchCell. +id<GREYMatcher> LegacySyncSwitchCell(NSString* accessibilityLabel, + BOOL isToggledOn); // Matcher for the Open in New Tab option in the context menu when long pressing // a link.
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.mm b/ios/chrome/test/earl_grey/chrome_matchers.mm index e8043b9..205ffb0 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers.mm +++ b/ios/chrome/test/earl_grey/chrome_matchers.mm
@@ -27,7 +27,6 @@ #import "ios/chrome/browser/ui/settings/cells/clear_browsing_data_constants.h" #import "ios/chrome/browser/ui/settings/cells/legacy/legacy_settings_switch_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_switch_item.h" -#import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h" #import "ios/chrome/browser/ui/settings/clear_browsing_data_collection_view_controller.h" #import "ios/chrome/browser/ui/settings/clear_browsing_data_ui_constants.h" #import "ios/chrome/browser/ui/settings/import_data_table_view_controller.h" @@ -301,8 +300,8 @@ grey_sufficientlyVisible(), nil); } -id<GREYMatcher> SyncSwitchCell(NSString* accessibilityLabel, - BOOL is_toggled_on) { +id<GREYMatcher> LegacySyncSwitchCell(NSString* accessibilityLabel, + BOOL is_toggled_on) { return grey_allOf( grey_accessibilityLabel(accessibilityLabel), grey_accessibilityValue(
diff --git a/ios/web/web_state/js/resources/find_in_page.js b/ios/web/web_state/js/resources/find_in_page.js index c3e99cec..4b95fbd 100644 --- a/ios/web/web_state/js/resources/find_in_page.js +++ b/ios/web/web_state/js/resources/find_in_page.js
@@ -24,6 +24,986 @@ // Store common namespace object in a global __gCrWeb object referenced by a // string, so it does not get renamed by closure compiler during the // minification. - __gCrWeb['findInPage'] = __gCrWeb.findInPage; +__gCrWeb['findInPage'] = __gCrWeb.findInPage; + +/** + * A string made by concatenating textContent.toLowerCase() of all TEXT nodes + * within current web page. + * @type {string} + */ +let allText_ = ''; + +/** + * A Section contains the info of one TEXT node in the |allText_|. The node's + * textContent is [begin, end) of |allText_|. + */ +class Section { + /** + * @param {number} begin Beginning index of |node|.textContent in |allText_|. + * @param {number} end Ending index of |node|.textContent in |allText_|. + * @param {Node} node The TEXT Node of this section. + */ + constructor(begin, end, node) { + this.begin = begin; + this.end = end; + this.node = node; + } +} + +/** + * All the sections_ in |allText_|. + * @type {Array<Section>} + */ +let sections_ = []; + +/** + * The index of the Section where the last PartialMatch is found. + */ +let sectionsIndex_ = 0; + +/** + * Do binary search in |sections_|[sectionsIndex_, ...) to find the first + * Section S which has S.end > |index|. + * @param {number} index The search target. This should be a valid index of + * |allText_|. + * @return {number} The index of the result in |sections_|. + */ +function findFirstSectionEndsAfter_(index) { + let left = sectionsIndex_; + let right = sections_.length; + while (left < right) { + let mid = Math.floor((left + right) / 2); + if (sections_[mid].end <= index) { + left = mid + 1; + } else { + right = mid; + } + } + return left; +} + +/** + * A Match represents a match result in the document. |this.nodes| stores all + * the <chrome_find> Nodes created for highlighting the matched text. If it + * contains only one Node, it means the match is found within one HTML TEXT + * Node, otherwise the match involves multiple HTML TEXT Nodes. + */ +class Match { + constructor() { + this.nodes = []; + } + + /** + * Returns if all <chrome_find> Nodes of this match are visible. + * @return {Boolean} If the Match is visible. + */ + visible() { + for (let i = 0; i < this.nodes.length; ++i) { + if (!isElementVisible_(this.nodes[i])) + return false; + } + return true; + } + + /** + * Adds orange color highlight for "selected match result", over the yellow + * color highlight for "normal match result". + * @return {undefined} + */ + addSelectHighlight() { + for (let i = 0; i < this.nodes.length; ++i) { + this.nodes[i].className = (this.nodes[i].className || '') + ' findysel'; + } + } + + /** + * Clears the orange color highlight. + * @return {undefined} + */ + removeSelectHighlight() { + for (let i = 0; i < this.nodes.length; ++i) { + this.nodes[i].className = + (this.nodes[i].className || '').replace(/\sfindysel/g, ''); + } + } +} + +/** + * The list of all the matches in current page. + * @type {Array<Match>} + */ +__gCrWeb.findInPage.matches = []; + +/** + * Index of the current highlighted choice. -1 means none. + * @type {number} + */ +__gCrWeb.findInPage.selectedMatchIndex = -1; + +/** + * The ID for the next Match found in |allText_|. This ID is used for + * identifying PartialMatches of the Match, so that when + * |processPartialMatchesInCurrentSection| is called, the <chrome_find> Nodes + * created for each PartialMatch can be recorded in the corresponding Match. + */ +let matchId_ = 0; + +/** + * A part of a Match, within a Section. A Match may cover multiple sections_ in + * |allText_|, so it must be split into multiple PartialMatches and then + * dispatched into the Sections they belong. The range of a PartialMatch in + * |allText_| is [begin, end). Exactly one <chrome_find> will be created for + * each PartialMatch. + */ +class PartialMatch { + /** + * @param {number} matchId ID of the Match to which this PartialMatch belongs. + * @param {number} begin Beginning index of partial match text in |allText_|. + * @param {number} end Ending index of partial match text in |allText_|. + */ + constructor(matchId, begin, end) { + this.matchId = matchId; + this.begin = begin; + this.end = end; + } +} + +/** + * A temporary array used for storing all PartialMatches inside current Section. + * @type {Array<PartialMatch>} + */ +let partialMatches_ = []; + +/** + * A Replacement represents a DOM operation that swaps |oldNode| with |newNodes| + * under the parent of |oldNode| to highlight the match result inside |oldNode|. + * |newNodes| may contain plain TEXT Nodes for unhighlighted parts and + * <chrome_find> nodes for highlighted parts. This operation will be executed + * reversely when clearing current highlights for next FindInPage action. + */ +class Replacement { + /** + * @param {Node} oldNode The HTML Node containing search result. + * @param {Array<Node>} newNodes New HTML Nodes created for substitution of + * |oldNode|. + */ + constructor(oldNode, newNodes) { + this.oldNode = oldNode; + this.newNodes = newNodes; + } + + /** + * Executes the replacement to highlight search result. + * @return {undefined} + */ + doSwap() { + let parentNode = this.oldNode.parentNode; + if (!parentNode) + return; + for (var i = 0; i < this.newNodes.length; ++i) { + parentNode.insertBefore(this.newNodes[i], this.oldNode); + } + parentNode.removeChild(this.oldNode); + } + + /** + * Executes the replacement reversely to clear the highlight. + * @return {undefined} + */ + undoSwap() { + let parentNode = this.newNodes[0].parentNode; + if (!parentNode) + return; + parentNode.insertBefore(this.oldNode, this.newNodes[0]); + for (var i = 0; i < this.newNodes.length; ++i) { + parentNode.removeChild(this.newNodes[i]); + } + } +} + +/** + * The replacements of current FindInPage action. + * @type {Array<Replacement>} + */ +let replacements_ = []; + +/** + * The index of the Replacement from which the highlight process continue when + * pumpSearch is called. + * @type {Number} + */ +let replacementsIndex_ = 0; + +/** + * Process all PartialMatches inside current Section. For current Section's + * node.textContent, all texts that are match results will be wrapped in + * <chrome_find>, and other texts will be put inside plain TEXT Nodes. All + * created Nodes will be stored in the Replacement of current Section, and all + * <chrome_find> Nodes will also be recorded in their belonging Matches. + * |partialMatches_| will be cleared when processing ends. + * @return {undefined} + */ +function processPartialMatchesInCurrentSection() { + if (partialMatches_.length == 0) + return; + let section = sections_[sectionsIndex_]; + let oldNode = section.node; + let newNodes = []; + let previousEnd = section.begin; + for (let i = 0; i < partialMatches_.length; ++i) { + let partialMatch = partialMatches_[i]; + // Create the TEXT node for leading non-matching string piece. Notice that + // substr must be taken from TEXT Node.textContent instead of |allText_| + // since it's in lower case. + if (partialMatch.begin > previousEnd) { + newNodes.push( + oldNode.ownerDocument.createTextNode(oldNode.textContent.substring( + previousEnd - section.begin, + partialMatch.begin - section.begin))); + } + // Create the <chrome_find> Node for matching text. + let newNode = oldNode.ownerDocument.createElement('chrome_find'); + newNode.setAttribute('class', CSS_CLASS_NAME); + newNode.innerHTML = escapeHTML_(oldNode.textContent.substring( + partialMatch.begin - section.begin, partialMatch.end - section.begin)); + newNodes.push(newNode); + previousEnd = partialMatch.end; + + // Record the <chrome_find> Node in corresponding Match. + __gCrWeb.findInPage.matches[partialMatch.matchId].nodes.push(newNode); + } + // Create the TEXT node for trailing non-matching string piece. + if (previousEnd != section.end) { + newNodes.push( + oldNode.ownerDocument.createTextNode(oldNode.textContent.substring( + previousEnd - section.begin, section.end - section.begin))); + } + + // Create the Replacement of current Section. + replacements_.push(new Replacement(oldNode, newNodes)); + + partialMatches_ = []; +} + +/** + * The list of frame documents. + * TODO(crbug.com/895529): x-domain frames won't work. + * @type {Array<Document>} + */ +let frameDocs_ = []; + +/** + * The style DOM element that we add. + * @type {Element} + */ +let styleElement_ = null; + +/** + * Width we expect the page to be. For example (320/480) for iphone, + * (1024/768) for ipad. + * @type {number} + */ +let pageWidth_ = 320; + +/** + * Height we expect the page to be. + * @type {number} + */ +let pageHeight_ = 480; + +/** + * Maximum number of visible elements to count + * @type {number} + */ +const MAX_VISIBLE_ELEMENTS = 100; + +/** + * A search is in progress. + * @type {boolean} + */ +let searchInProgress_ = false; + +/** + * Node names that are not going to be processed. + * @type {Object} + */ +const IGNORE_NODE_NAMES = + new Set(['SCRIPT', 'STYLE', 'EMBED', 'OBJECT', 'SELECT', 'TEXTAREA']); + +/** + * Class name of CSS element. + * @type {string} + */ +const CSS_CLASS_NAME = 'find_in_page'; + +/** + * ID of CSS style. + * @type {string} + */ +const CSS_STYLE_ID = '__gCrWeb.findInPageStyle'; + +/** + * Result passed back to app to indicate no results for the query. + * @type {string} + */ +const NO_RESULTS = '[0,[0,0,0]]'; + +/** + * Result passed back to app to indicate pumpSearch has reached timeout. + * @type {string} + */ +const TIMEOUT = '[false]'; + +/** + * Regex to escape regex special characters in a string. + * @type {RegExp} + */ +const REGEX_ESCAPER = /([.?*+^$[\]\\(){}|-])/g; + +/** + * @return {Match} The currently selected Match. + */ +function getCurrentSelectedMatch_() { + return __gCrWeb.findInPage.matches[__gCrWeb.findInPage.selectedMatchIndex]; +}; + +/** + * Creates the regex needed to find the text. + * @param {string} findText Phrase to look for. + * @return {RegExp} regex needed to find the text. + */ +function getRegex_(findText) { + let regexString = '(' + escapeRegex_(findText) + ')'; + return new RegExp(regexString, 'ig'); +}; + +/** + * A timer that checks timeout for long tasks. + */ +class Timer { + /** + * @param {Number} timeoutMs Timeout in milliseconds. + */ + constructor(timeoutMs) { + this.beginTime = Date.now(); + this.timeoutMs = timeoutMs; + } + + /** + * @return {Boolean} Whether this timer has been reached. + */ + overtime() { + return Date.now() - this.beginTime > this.timeoutMs; + } +} + +/** + * Looks for a phrase in the DOM. + * @param {string} findText Phrase to look for like "ben franklin". + * @param {number} timeout Maximum time to run. + * @return {string} How many results there are in the page in the form of + [highlightedWordsCount, [index, pageLocationX, pageLocationY]]. + */ +__gCrWeb.findInPage.highlightWord = function(findText, timeout) { + if (__gCrWeb.findInPage.matches && __gCrWeb.findInPage.matches.length) { + // Clean up a previous run. + cleanUp_(); + } + if (!findText) { + // No searching for emptyness. + return NO_RESULTS; + } + + // Holds what nodes we have not processed yet. + __gCrWeb.findInPage.stack = []; + + // Push frames into stack too. + for (let i = frameDocs_.length - 1; i >= 0; i--) { + let doc = frameDocs_[i]; + __gCrWeb.findInPage.stack.push(doc); + } + __gCrWeb.findInPage.stack.push(document.body); + + // Number of visible elements found. + __gCrWeb.findInPage.visibleFound = 0; + + // Index tracking variables so search can be broken up into multiple calls. + __gCrWeb.findInPage.visibleIndex = 0; + + __gCrWeb.findInPage.regex = getRegex_(findText); + + searchInProgress_ = true; + + return __gCrWeb.findInPage.pumpSearch(timeout); +}; + +/** + * Do following steps: + * 1. Do a DFS in the page, concatenate all TEXT Nodes' content into + * |allText_|, and create |sections_| to record which part of |allText_| + * belongs to which Node; + * 2. Do regex match in |allText_| to find all matches, create |replacements_| + * for highlighting all results and |__gCrWeb.findInPage.matches| for + * highlighting selected result; + * 3. Execute |replacements_| to highlight all results; + * 4. Check the visibility of each Match; + * 5. Call __gCrWeb.findInPage.goNext. + * + * If |timeout| has been reached, the function will return TIMEOUT, and the + * caller need to call this function again to continue searching. This prevents + * the Js thread from blocking the WebView's UI. + * + * @param {number} timeout Only run find in page until timeout. + * @return {string} string in the form of "[bool, int]", where bool indicates + whether the text was found and int indicates text position. + */ +__gCrWeb.findInPage.pumpSearch = function(timeout) { + // TODO(crbug.com/895531): It would be better if this DCHECKed. + if (searchInProgress_ == false) + return NO_RESULTS; + + let timer = new Timer(timeout); + + // Go through every node in DFS fashion. + while (__gCrWeb.findInPage.stack.length) { + let node = __gCrWeb.findInPage.stack.pop(); + let children = node.childNodes; + if (children && children.length) { + // add all (reasonable) children + for (let i = children.length - 1; i >= 0; --i) { + let child = children[i]; + if ((child.nodeType == 1 || child.nodeType == 3) && + !IGNORE_NODE_NAMES.has(child.nodeName)) { + __gCrWeb.findInPage.stack.push(children[i]); + } + } + } + + // Build up |allText_| and |sections_|. + if (node.nodeType == 3 && node.parentNode) { + sections_.push(new Section( + allText_.length, allText_.length + node.textContent.length, node)); + allText_ += node.textContent.toLowerCase(); + } + + if (timer.overtime()) + return TIMEOUT; + } + + // Do regex match in |allText_|, create |matches| and |replacements|. The + // regex is set on __gCrWeb, so its state is kept between continuous calls on + // pumpSearch. + let regex = __gCrWeb.findInPage.regex; + if (regex) { + for (let res; res = regex.exec(allText_);) { + // The range of current Match in |allText_| is [begin, end). + let begin = res.index; + let end = begin + res[0].length; + __gCrWeb.findInPage.matches.push(new Match()); + + // Find the Section where current Match starts. + let oldSectionIndex = sectionsIndex_; + let newSectionIndex = findFirstSectionEndsAfter_(begin); + // If current Match starts at a new Section, process current Section and + // move to the new Section. + if (newSectionIndex > oldSectionIndex) { + processPartialMatchesInCurrentSection(); + sectionsIndex_ = newSectionIndex; + } + + // Create all PartialMatches of current Match. + while (true) { + let section = sections_[sectionsIndex_]; + partialMatches_.push(new PartialMatch( + matchId_, Math.max(section.begin, begin), + Math.min(section.end, end))); + // If current Match.end exceeds current Section.end, process current + // Section and move to next Section. + if (section.end < end) { + processPartialMatchesInCurrentSection(); + ++sectionsIndex_; + } else { + // Current Match ends in current Section. + break; + } + } + ++matchId_; + + if (timer.overtime()) + return TIMEOUT; + } + // Process remaining PartialMatches. + processPartialMatchesInCurrentSection(); + __gCrWeb.findInPage.regex = undefined; + } + + // Execute replacements to highlight search results. + for (let i = replacementsIndex_; i < replacements_.length; ++i) { + if (timer.overtime()) { + replacementsIndex_ = i; + return TIMEOUT; + } + replacements_[i].doSwap(); + } + + // Count visible elements. + let max = __gCrWeb.findInPage.matches.length; + let maxVisible = MAX_VISIBLE_ELEMENTS; + for (let index = __gCrWeb.findInPage.visibleIndex; index < max; index++) { + let match = __gCrWeb.findInPage.matches[index]; + if (timer.overtime()) { + __gCrWeb.findInPage.visibleIndex = index; + return TIMEOUT; + } + + // Stop after |maxVisible| elements. + if (__gCrWeb.findInPage.visibleFound > maxVisible) { + match.visibleIndex = maxVisible; + continue; + } + + if (match.visible()) { + __gCrWeb.findInPage.visibleFound++; + match.visibleIndex = __gCrWeb.findInPage.visibleFound; + } + } + + searchInProgress_ = false; + + let pos = __gCrWeb.findInPage.goNext(); + if (pos) { + return '[' + __gCrWeb.findInPage.visibleFound + ',' + pos + ']'; + } else { + return NO_RESULTS; + } +}; + +/** + * Removes highlights of previous search and reset all global vars. + * @return {undefined} + */ +function cleanUp_() { + for (let i = 0; i < replacements_.length; ++i) { + replacements_[i].undoSwap(); + } + + allText_ = ''; + sections_ = []; + sectionsIndex_ = 0; + + __gCrWeb.findInPage.matches = []; + __gCrWeb.findInPage.selectedMatchIndex = -1; + matchId_ = 0; + partialMatches_ = []; + + replacements_ = []; + replacementsIndex_ = 0; +}; + +/** + * Increments the index of the current selected Match or, if the index is + * already at the end, sets it to the index of the first Match in the page. + */ +__gCrWeb.findInPage.incrementIndex = function() { + if (__gCrWeb.findInPage.selectedMatchIndex >= + __gCrWeb.findInPage.matches.length - 1) { + __gCrWeb.findInPage.selectedMatchIndex = 0; + } else { + __gCrWeb.findInPage.selectedMatchIndex++; + } +}; + +/** + * Switches to the next result, animating a little highlight in the process. + * @return {string} JSON encoded array of coordinates to scroll to, or blank if + * nothing happened. + */ +__gCrWeb.findInPage.goNext = function() { + if (!__gCrWeb.findInPage.matches || __gCrWeb.findInPage.matches.length == 0) { + return ''; + } + if (__gCrWeb.findInPage.selectedMatchIndex >= 0) { + // Remove previous highlight. + getCurrentSelectedMatch_().removeSelectHighlight(); + } + // Iterate through to the next index, but because they might not be visible, + // keep trying until you find one that is. Make sure we don't loop forever by + // stopping on what we are currently highlighting. + let oldIndex = __gCrWeb.findInPage.selectedMatchIndex; + __gCrWeb.findInPage.incrementIndex(); + while (!getCurrentSelectedMatch_().visible()) { + if (oldIndex === __gCrWeb.findInPage.selectedMatchIndex) { + // Checked all matches but didn't find anything else visible. + return ''; + } + __gCrWeb.findInPage.incrementIndex(); + if (0 === __gCrWeb.findInPage.selectedMatchIndex && oldIndex < 0) { + // Didn't find anything visible and haven't highlighted anything yet. + return ''; + } + } + // Return scroll dimensions. + return findScrollDimensions_(); +}; + +/** + * Decrements the index of the current selected Match or, if the index is + * already at the beginning, sets it to the index of the last Match in the page. + */ +__gCrWeb.findInPage.decrementIndex = function() { + if (__gCrWeb.findInPage.selectedMatchIndex <= 0) { + __gCrWeb.findInPage.selectedMatchIndex = + __gCrWeb.findInPage.matches.length - 1; + } else { + __gCrWeb.findInPage.selectedMatchIndex--; + } +}; + +/** + * Switches to the previous result, animating a little highlight in the process. + * @return {string} JSON encoded array of coordinates to scroll to, or blank if + * nothing happened. + */ +__gCrWeb.findInPage.goPrev = function() { + if (!__gCrWeb.findInPage.matches || __gCrWeb.findInPage.matches.length == 0) { + return ''; + } + if (__gCrWeb.findInPage.selectedMatchIndex >= 0) { + // Remove previous highlight. + getCurrentSelectedMatch_().removeSelectHighlight(); + } + // Iterate through to the next index, but because they might not be visible, + // keep trying until you find one that is. Make sure we don't loop forever by + // stopping on what we are currently highlighting. + let old = __gCrWeb.findInPage.selectedMatchIndex; + __gCrWeb.findInPage.decrementIndex(); + while (!getCurrentSelectedMatch_().visible()) { + __gCrWeb.findInPage.decrementIndex(); + if (old == __gCrWeb.findInPage.selectedMatchIndex) { + // Checked all matches but didn't find anything. + return ''; + } + } + + // Return scroll dimensions. + return findScrollDimensions_(); +}; + +/** + * Normalize coordinates according to the current document dimensions. Don't go + * too far off the screen in either direction. Try to center if possible. + * @param {Element} elem Element to find normalized coordinates for. + * @return {Array<number>} Normalized coordinates. + */ +function getNormalizedCoordinates_(elem) { + let pos = findAbsolutePosition_(elem); + let maxX = Math.max(getBodyWidth_(), pos[0] + elem.offsetWidth); + let maxY = Math.max(getBodyHeight_(), pos[1] + elem.offsetHeight); + // Don't go too far off the screen in either direction. Try to center if + // possible. + let xPos = Math.max( + 0, Math.min(maxX - window.innerWidth, pos[0] - (window.innerWidth / 2))); + let yPos = Math.max( + 0, + Math.min(maxY - window.innerHeight, pos[1] - (window.innerHeight / 2))); + return [xPos, yPos]; +}; + +/** + * Scale coordinates according to the width of the screen, in case the screen + * is zoomed out. + * @param {Array<number>} coordinates Coordinates to scale. + * @return {Array<number>} Scaled coordinates. + */ +function scaleCoordinates_(coordinates) { + let scaleFactor = pageWidth_ / window.innerWidth; + return [coordinates[0] * scaleFactor, coordinates[1] * scaleFactor]; +}; + +/** + * Finds the position of the result. + * @return {string} JSON encoded array of the scroll coordinates "[x, y]". + */ +function findScrollDimensions_() { + let match = getCurrentSelectedMatch_(); + if (!match) { + return ''; + } + let normalized = getNormalizedCoordinates_(match.nodes[0]); + let xPos = normalized[0]; + let yPos = normalized[1]; + + match.addSelectHighlight(); + let scaled = scaleCoordinates_(normalized); + let index = match.visibleIndex; + scaled.unshift(index); + return __gCrWeb.stringify(scaled); +}; + +/** + * Initialize the __gCrWeb.findInPage module. + * @param {number} width Width of page. + * @param {number} height Height of page. + + */ +__gCrWeb.findInPage.init = function(width, height) { + if (__gCrWeb.findInPage.hasInitialized) { + return; + } + pageWidth_ = width; + pageHeight_ = height; + frameDocs_ = getFrameDocuments_(); + enable_(); + __gCrWeb.findInPage.hasInitialized = true; +}; + +/** + * Enable the __gCrWeb.findInPage module. + * Mainly just adds the style for the classes. + */ +function enable_() { + if (styleElement_) { + // Already enabled. + return; + } + addStyle_(); +}; + +/** + * Gets the scale ratio between the application window and the web document. + * @return {number} Scale. + */ +function getPageScale_() { + return (pageWidth_ / getBodyWidth_()); +}; + +/** + * Adds the appropriate style element to the page. + */ +function addStyle_() { + addDocumentStyle_(document); + for (let i = frameDocs_.length - 1; i >= 0; i--) { + let doc = frameDocs_[i]; + addDocumentStyle_(doc); + } +}; + +function addDocumentStyle_(thisDocument) { + let styleContent = []; + function addCSSRule(name, style) { + styleContent.push(name, '{', style, '}'); + }; + let scale = getPageScale_(); + let zoom = (1.0 / scale); + let left = ((1 - scale) / 2 * 100); + addCSSRule( + '.' + CSS_CLASS_NAME, + 'background-color:#ffff00 !important;' + + 'padding:0px;margin:0px;' + + 'overflow:visible !important;'); + addCSSRule( + '.findysel', + 'background-color:#ff9632 !important;' + + 'padding:0px;margin:0px;' + + 'overflow:visible !important;'); + styleElement_ = thisDocument.createElement('style'); + styleElement_.id = CSS_STYLE_ID; + styleElement_.setAttribute('type', 'text/css'); + styleElement_.appendChild(thisDocument.createTextNode(styleContent.join(''))); + thisDocument.body.appendChild(styleElement_); +}; + +/** + * Removes the style element from the page. + */ +function removeStyle_() { + if (styleElement_) { + removeDocumentStyle_(document); + for (let i = frameDocs_.length - 1; i >= 0; i--) { + let doc = frameDocs_[i]; + removeDocumentStyle_(doc); + } + styleElement_ = null; + } +}; + +function removeDocumentStyle_(thisDocument) { + let style = thisDocument.getElementById(CSS_STYLE_ID); + thisDocument.body.removeChild(style); +}; + +/** + * Disables the __gCrWeb.findInPage module. + * Basically just removes the style and class names. + */ +__gCrWeb.findInPage.disable = function() { + if (styleElement_) { + removeStyle_(); + window.setTimeout(cleanUp_, 0); + } + __gCrWeb.findInPage.hasInitialized = false; +}; + +/** + * Returns the width of the document.body. Sometimes though the body lies to + * try to make the page not break rails, so attempt to find those as well. + * An example: wikipedia pages for the ipad. + * @return {number} Width of the document body. + */ +function getBodyWidth_() { + let body = document.body; + let documentElement = document.documentElement; + return Math.max( + body.scrollWidth, documentElement.scrollWidth, body.offsetWidth, + documentElement.offsetWidth, body.clientWidth, + documentElement.clientWidth); +}; + +/** + * Returns the height of the document.body. Sometimes though the body lies to + * try to make the page not break rails, so attempt to find those as well. + * An example: wikipedia pages for the ipad. + * @return {number} Height of the document body. + */ +function getBodyHeight_() { + let body = document.body; + let documentElement = document.documentElement; + return Math.max( + body.scrollHeight, documentElement.scrollHeight, body.offsetHeight, + documentElement.offsetHeight, body.clientHeight, + documentElement.clientHeight); +}; + +/** + * Helper function that determines if an element is visible. + * @param {Element} elem Element to check. + * @return {boolean} Whether elem is visible or not. + */ +function isElementVisible_(elem) { + if (!elem) { + return false; + } + let top = 0; + let left = 0; + let bottom = Infinity; + let right = Infinity; + + let originalElement = elem; + let nextOffsetParent = originalElement.offsetParent; + + // We are currently handling all scrolling through the app, which means we can + // only scroll the window, not any scrollable containers in the DOM itself. So + // for now this function returns false if the element is scrolled outside the + // viewable area of its ancestors. + // TODO(crbug.com/915357): handle scrolling within the DOM. + let bodyHeight = getBodyHeight_(); + let bodyWidth = getBodyWidth_(); + + while (elem && elem.nodeName.toUpperCase() != 'BODY') { + let computedStyle = + elem.ownerDocument.defaultView.getComputedStyle(elem, null); + + if (elem.style.display === 'none' || elem.style.visibility === 'hidden' || + elem.style.opacity === 0 || computedStyle.display === 'none' || + computedStyle.visibility === 'hidden' || computedStyle.opacity === 0) { + return false; + } + + // For the original element and all ancestor offsetParents, trim down the + // visible area of the original element. + if (elem.isSameNode(originalElement) || elem.isSameNode(nextOffsetParent)) { + let visible = elem.getBoundingClientRect(); + if (elem.style.overflow === 'hidden' && + (visible.width === 0 || visible.height === 0)) + return false; + + top = Math.max(top, visible.top + window.pageYOffset); + bottom = Math.min(bottom, visible.bottom + window.pageYOffset); + left = Math.max(left, visible.left + window.pageXOffset); + right = Math.min(right, visible.right + window.pageXOffset); + + // The element is not within the original viewport. + let notWithinViewport = top < 0 || left < 0; + + // The element is flowing off the boundary of the page. Note this is + // not comparing to the size of the window, but the calculated offset + // size of the document body. This can happen if the element is within + // a scrollable container in the page. + let offPage = right > bodyWidth || bottom > bodyHeight; + if (notWithinViewport || offPage) { + return false; + } + nextOffsetParent = elem.offsetParent; + } + + elem = elem.parentNode; + } + return true; +}; + +/** + * Helper function to find the absolute position of an element on the page. + * @param {Element} elem Element to check. + * @return {Array<number>} [x, y] positions. + */ +function findAbsolutePosition_(elem) { + let boundingRect = elem.getBoundingClientRect(); + return [ + boundingRect.left + window.pageXOffset, + boundingRect.top + window.pageYOffset + ]; +}; + +/** + * @param {string} text Text to escape. + * @return {string} escaped text. + */ +function escapeHTML_(text) { + let unusedDiv = document.createElement('div'); + unusedDiv.innerText = text; + return unusedDiv.innerHTML; +}; + +/** + * Escapes regexp special characters. + * @param {string} text Text to escape. + * @return {string} escaped text. + */ +function escapeRegex_(text) { + return text.replace(REGEX_ESCAPER, '\\$1'); +}; + +/** + * Gather all iframes in the main window. + * @return {Array<Document>} frames. + */ +function getFrameDocuments_() { + let windowsToSearch = [window]; + let documents = []; + while (windowsToSearch.length != 0) { + let win = windowsToSearch.pop(); + for (let i = win.frames.length - 1; i >= 0; i--) { + // The following try/catch catches a webkit error when searching a page + // with iframes. See crbug.com/702566 for details. + // To verify that this is still necessary: + // 1. Remove this try/catch. + // 2. Go to a page with iframes. + // 3. Search for anything. + // 4. Check if the webkit debugger spits out SecurityError (DOM Exception) + // and the search fails. If it doesn't, feel free to remove this. + try { + if (win.frames[i].document) { + documents.push(win.frames[i].document); + windowsToSearch.push(win.frames[i]); + } + } catch (e) { + // Do nothing. + } + } + } + return documents; +}; + +window.addEventListener('pagehide', __gCrWeb.findInPage.disable); })();
diff --git a/media/audio/BUILD.gn b/media/audio/BUILD.gn index 3b4709240..ae293df 100644 --- a/media/audio/BUILD.gn +++ b/media/audio/BUILD.gn
@@ -20,8 +20,12 @@ } config("platform_config") { + defines = [] + if (is_chromecast) { + defines += [ "IS_CHROMECAST" ] + } if (use_alsa) { - defines = [ "USE_ALSA" ] + defines += [ "USE_ALSA" ] } } @@ -353,6 +357,12 @@ "//testing/gmock", "//testing/gtest", ] + if (use_alsa) { + sources += [ + "alsa/mock_alsa_wrapper.cc", + "alsa/mock_alsa_wrapper.h", + ] + } } source_set("unit_tests") { @@ -446,6 +456,7 @@ if (use_alsa) { sources += [ "alsa/alsa_output_unittest.cc", + "alsa/alsa_util_unittest.cc", "audio_low_latency_input_output_unittest.cc", ] }
diff --git a/media/audio/alsa/alsa_input.cc b/media/audio/alsa/alsa_input.cc index 13fb7c60..28a0ed6b 100644 --- a/media/audio/alsa/alsa_input.cc +++ b/media/audio/alsa/alsa_input.cc
@@ -56,18 +56,18 @@ if (device_handle_) return false; // Already open. - uint32_t latency_us = - buffer_duration_.InMicroseconds() * kNumPacketsInRingBuffer; + uint32_t packet_us = buffer_duration_.InMicroseconds(); + uint32_t buffer_us = packet_us * kNumPacketsInRingBuffer; // Use the same minimum required latency as output. - latency_us = std::max(latency_us, AlsaPcmOutputStream::kMinLatencyMicros); + buffer_us = std::max(buffer_us, AlsaPcmOutputStream::kMinLatencyMicros); if (device_name_ == kAutoSelectDevice) { const char* device_names[] = { kDefaultDevice1, kDefaultDevice2 }; for (size_t i = 0; i < arraysize(device_names); ++i) { device_handle_ = alsa_util::OpenCaptureDevice( wrapper_, device_names[i], params_.channels(), params_.sample_rate(), - kAlsaSampleFormat, latency_us); + kAlsaSampleFormat, buffer_us, packet_us); if (device_handle_) { device_name_ = device_names[i]; @@ -77,7 +77,7 @@ } else { device_handle_ = alsa_util::OpenCaptureDevice( wrapper_, device_name_.c_str(), params_.channels(), - params_.sample_rate(), kAlsaSampleFormat, latency_us); + params_.sample_rate(), kAlsaSampleFormat, buffer_us, packet_us); } if (device_handle_) {
diff --git a/media/audio/alsa/alsa_output_unittest.cc b/media/audio/alsa/alsa_output_unittest.cc index 8150c329..bca316b 100644 --- a/media/audio/alsa/alsa_output_unittest.cc +++ b/media/audio/alsa/alsa_output_unittest.cc
@@ -15,6 +15,7 @@ #include "media/audio/alsa/alsa_output.h" #include "media/audio/alsa/alsa_wrapper.h" #include "media/audio/alsa/audio_manager_alsa.h" +#include "media/audio/alsa/mock_alsa_wrapper.h" #include "media/audio/fake_audio_log_factory.h" #include "media/audio/mock_audio_source_callback.h" #include "media/audio/test_audio_thread.h" @@ -42,42 +43,6 @@ namespace media { -class MockAlsaWrapper : public AlsaWrapper { - public: - MOCK_METHOD3(DeviceNameHint, int(int card, - const char* iface, - void*** hints)); - MOCK_METHOD2(DeviceNameGetHint, char*(const void* hint, const char* id)); - MOCK_METHOD1(DeviceNameFreeHint, int(void** hints)); - - MOCK_METHOD4(PcmOpen, int(snd_pcm_t** handle, const char* name, - snd_pcm_stream_t stream, int mode)); - MOCK_METHOD1(PcmClose, int(snd_pcm_t* handle)); - MOCK_METHOD1(PcmPrepare, int(snd_pcm_t* handle)); - MOCK_METHOD1(PcmDrop, int(snd_pcm_t* handle)); - MOCK_METHOD2(PcmDelay, int(snd_pcm_t* handle, snd_pcm_sframes_t* delay)); - MOCK_METHOD3(PcmWritei, snd_pcm_sframes_t(snd_pcm_t* handle, - const void* buffer, - snd_pcm_uframes_t size)); - MOCK_METHOD3(PcmReadi, snd_pcm_sframes_t(snd_pcm_t* handle, - void* buffer, - snd_pcm_uframes_t size)); - MOCK_METHOD3(PcmRecover, int(snd_pcm_t* handle, int err, int silent)); - MOCK_METHOD7(PcmSetParams, int(snd_pcm_t* handle, snd_pcm_format_t format, - snd_pcm_access_t access, unsigned int channels, - unsigned int rate, int soft_resample, - unsigned int latency)); - MOCK_METHOD3(PcmGetParams, int(snd_pcm_t* handle, - snd_pcm_uframes_t* buffer_size, - snd_pcm_uframes_t* period_size)); - MOCK_METHOD1(PcmName, const char*(snd_pcm_t* handle)); - MOCK_METHOD1(PcmAvailUpdate, snd_pcm_sframes_t(snd_pcm_t* handle)); - MOCK_METHOD1(PcmState, snd_pcm_state_t(snd_pcm_t* handle)); - MOCK_METHOD1(PcmStart, int(snd_pcm_t* handle)); - - MOCK_METHOD1(StrError, const char*(int errnum)); -}; - class MockAudioManagerAlsa : public AudioManagerAlsa { public: MockAudioManagerAlsa()
diff --git a/media/audio/alsa/alsa_util.cc b/media/audio/alsa/alsa_util.cc index 127e1719..84b4133 100644 --- a/media/audio/alsa/alsa_util.cc +++ b/media/audio/alsa/alsa_util.cc
@@ -6,33 +6,231 @@ #include <stddef.h> +#include <functional> +#include <memory> + #include "base/logging.h" +#include "base/time/time.h" #include "media/audio/alsa/alsa_wrapper.h" namespace alsa_util { +namespace { + +// Set hardware parameters of PCM. It does the same thing as the corresponding +// part in snd_pcm_set_params() (https://www.alsa-project.org, source code: +// https://github.com/tiwai/alsa-lib/blob/master/src/pcm/pcm.c#L8459), except +// that it configures buffer size and period size both to closest available +// values instead of forcing the buffer size be 4 times of the period size. +int ConfigureHwParams(media::AlsaWrapper* wrapper, + snd_pcm_t* handle, + snd_pcm_format_t format, + snd_pcm_access_t access, + unsigned int channels, + unsigned int sample_rate, + int soft_resample, + snd_pcm_uframes_t frames_per_buffer, + snd_pcm_uframes_t frames_per_period) { + int error = 0; + + snd_pcm_hw_params_t* hw_params = nullptr; + error = wrapper->PcmHwParamsMalloc(&hw_params); + if (error < 0) { + LOG(ERROR) << "PcmHwParamsMalloc: " << wrapper->StrError(error); + return error; + } + // |snd_pcm_hw_params_t| is not exposed and requires memory allocation through + // ALSA API. Therefore, use a smart pointer to pointer to insure freeing + // memory when the function returns. + std::unique_ptr<snd_pcm_hw_params_t*, + std::function<void(snd_pcm_hw_params_t**)>> + params_holder(&hw_params, [wrapper](snd_pcm_hw_params_t** params) { + wrapper->PcmHwParamsFree(*params); + }); + + error = wrapper->PcmHwParamsAny(handle, hw_params); + if (error < 0) { + LOG(ERROR) << "PcmHwParamsAny: " << wrapper->StrError(error); + return error; + } + + error = wrapper->PcmHwParamsSetRateResample(handle, hw_params, soft_resample); + if (error < 0) { + LOG(ERROR) << "PcmHwParamsSetRateResample: " << wrapper->StrError(error); + return error; + } + + error = wrapper->PcmHwParamsSetAccess(handle, hw_params, access); + if (error < 0) { + LOG(ERROR) << "PcmHwParamsSetAccess: " << wrapper->StrError(error); + return error; + } + + error = wrapper->PcmHwParamsSetFormat(handle, hw_params, format); + if (error < 0) { + LOG(ERROR) << "PcmHwParamsSetFormat: " << wrapper->StrError(error); + return error; + } + + error = wrapper->PcmHwParamsSetChannels(handle, hw_params, channels); + if (error < 0) { + LOG(ERROR) << "PcmHwParamsSetChannels: " << wrapper->StrError(error); + return error; + } + + unsigned int rate = sample_rate; + error = wrapper->PcmHwParamsSetRateNear(handle, hw_params, &rate, nullptr); + if (error < 0) { + LOG(ERROR) << "PcmHwParamsSetRateNear: " << wrapper->StrError(error); + return error; + } + if (rate != sample_rate) { + LOG(ERROR) << "Rate doesn't match, required: " << sample_rate + << "Hz, but get: " << rate << "Hz."; + return -EINVAL; + } + + error = wrapper->PcmHwParamsSetBufferSizeNear(handle, hw_params, + &frames_per_buffer); + if (error < 0) { + LOG(ERROR) << "PcmHwParamsSetBufferSizeNear: " << wrapper->StrError(error); + return error; + } + + int direction = 0; + error = wrapper->PcmHwParamsSetPeriodSizeNear(handle, hw_params, + &frames_per_period, &direction); + if (error < 0) { + LOG(ERROR) << "PcmHwParamsSetPeriodSizeNear: " << wrapper->StrError(error); + return error; + } + + if (frames_per_period > frames_per_buffer / 2) { + LOG(ERROR) << "Period size (" << frames_per_period + << ") is too big; buffer size = " << frames_per_buffer; + return -EINVAL; + } + + error = wrapper->PcmHwParams(handle, hw_params); + if (error < 0) + LOG(ERROR) << "PcmHwParams: " << wrapper->StrError(error); + + return error; +} + +// Set software parameters of PCM. It does the same thing as the corresponding +// part in snd_pcm_set_params() +// (https://github.com/tiwai/alsa-lib/blob/master/src/pcm/pcm.c#L8603). +int ConfigureSwParams(media::AlsaWrapper* wrapper, + snd_pcm_t* handle, + snd_pcm_uframes_t frames_per_buffer, + snd_pcm_uframes_t frames_per_period) { + int error = 0; + + snd_pcm_sw_params_t* sw_params = nullptr; + error = wrapper->PcmSwParamsMalloc(&sw_params); + if (error < 0) { + LOG(ERROR) << "PcmSwParamsMalloc: " << wrapper->StrError(error); + return error; + } + // |snd_pcm_sw_params_t| is not exposed and thus use a smart pointer to + // pointer to insure freeing memory when the function returns. + std::unique_ptr<snd_pcm_sw_params_t*, + std::function<void(snd_pcm_sw_params_t**)>> + params_holder(&sw_params, [wrapper](snd_pcm_sw_params_t** params) { + wrapper->PcmSwParamsFree(*params); + }); + + error = wrapper->PcmSwParamsCurrent(handle, sw_params); + if (error < 0) { + LOG(ERROR) << "PcmSwParamsCurrent: " << wrapper->StrError(error); + return error; + } + + // For playback, start the transfer when the buffer is almost full. + int start_threshold = + (frames_per_buffer / frames_per_period) * frames_per_period; + error = + wrapper->PcmSwParamsSetStartThreshold(handle, sw_params, start_threshold); + if (error < 0) { + LOG(ERROR) << "PcmSwParamsSetStartThreshold: " << wrapper->StrError(error); + return error; + } + + // For capture, wake capture thread as soon as possible (1 period). + error = wrapper->PcmSwParamsSetAvailMin(handle, sw_params, frames_per_period); + if (error < 0) { + LOG(ERROR) << "PcmSwParamsSetAvailMin: " << wrapper->StrError(error); + return error; + } + + error = wrapper->PcmSwParams(handle, sw_params); + if (error < 0) + LOG(ERROR) << "PcmSwParams: " << wrapper->StrError(error); + + return error; +} + +int SetParams(media::AlsaWrapper* wrapper, + snd_pcm_t* handle, + snd_pcm_format_t format, + unsigned int channels, + unsigned int rate, + unsigned int frames_per_buffer, + unsigned int frames_per_period) { + int error = ConfigureHwParams( + wrapper, handle, format, SND_PCM_ACCESS_RW_INTERLEAVED, channels, rate, + 1 /* Enable resampling */, frames_per_buffer, frames_per_period); + if (error == 0) { + error = ConfigureSwParams(wrapper, handle, frames_per_buffer, + frames_per_period); + } + return error; +} + +} // namespace + static snd_pcm_t* OpenDevice(media::AlsaWrapper* wrapper, const char* device_name, snd_pcm_stream_t type, int channels, int sample_rate, snd_pcm_format_t pcm_format, - int latency_us) { + int buffer_us, + int period_us = 0) { snd_pcm_t* handle = NULL; int error = wrapper->PcmOpen(&handle, device_name, type, SND_PCM_NONBLOCK); if (error < 0) { - LOG(WARNING) << "PcmOpen: " << device_name << "," - << wrapper->StrError(error); + LOG(ERROR) << "PcmOpen: " << device_name << "," << wrapper->StrError(error); return NULL; } - error = wrapper->PcmSetParams(handle, pcm_format, - SND_PCM_ACCESS_RW_INTERLEAVED, channels, - sample_rate, 1, latency_us); + error = + wrapper->PcmSetParams(handle, pcm_format, SND_PCM_ACCESS_RW_INTERLEAVED, + channels, sample_rate, 1, buffer_us); if (error < 0) { LOG(WARNING) << "PcmSetParams: " << device_name << ", " - << wrapper->StrError(error) << " - Format: " << pcm_format - << " Channels: " << channels << " Latency: " << latency_us; + << wrapper->StrError(error); + // Default parameter setting function failed, try again with the customized + // one if |period_us| is set, which is the case for capture but not for + // playback. + if (period_us > 0) { + const unsigned int frames_per_buffer = static_cast<unsigned int>( + static_cast<int64_t>(buffer_us) * sample_rate / + base::Time::kMicrosecondsPerSecond); + const unsigned int frames_per_period = static_cast<unsigned int>( + static_cast<int64_t>(period_us) * sample_rate / + base::Time::kMicrosecondsPerSecond); + LOG(WARNING) << "SetParams: " << device_name + << " - Format: " << pcm_format << " Channels: " << channels + << " Sample rate: " << sample_rate + << " Buffer size: " << frames_per_buffer + << " Period size: " << frames_per_period; + error = SetParams(wrapper, handle, pcm_format, channels, sample_rate, + frames_per_buffer, frames_per_period); + } + } + if (error < 0) { if (alsa_util::CloseDevice(wrapper, handle) < 0) { // TODO(ajwong): Retry on certain errors? LOG(WARNING) << "Unable to close audio device. Leaking handle."; @@ -78,9 +276,10 @@ int channels, int sample_rate, snd_pcm_format_t pcm_format, - int latency_us) { + int buffer_us, + int period_us) { return OpenDevice(wrapper, device_name, SND_PCM_STREAM_CAPTURE, channels, - sample_rate, pcm_format, latency_us); + sample_rate, pcm_format, buffer_us, period_us); } snd_pcm_t* OpenPlaybackDevice(media::AlsaWrapper* wrapper, @@ -88,9 +287,9 @@ int channels, int sample_rate, snd_pcm_format_t pcm_format, - int latency_us) { + int buffer_us) { return OpenDevice(wrapper, device_name, SND_PCM_STREAM_PLAYBACK, channels, - sample_rate, pcm_format, latency_us); + sample_rate, pcm_format, buffer_us); } snd_mixer_t* OpenMixer(media::AlsaWrapper* wrapper,
diff --git a/media/audio/alsa/alsa_util.h b/media/audio/alsa/alsa_util.h index d24584a..47b5d1b 100644 --- a/media/audio/alsa/alsa_util.h +++ b/media/audio/alsa/alsa_util.h
@@ -8,25 +8,32 @@ #include <alsa/asoundlib.h> #include <string> +#include "media/base/media_export.h" + namespace media { class AlsaWrapper; } namespace alsa_util { -snd_pcm_t* OpenCaptureDevice(media::AlsaWrapper* wrapper, - const char* device_name, - int channels, - int sample_rate, - snd_pcm_format_t pcm_format, - int latency_us); +// When opening ALSA devices, |period_us| is the size of a packet and +// |buffer_us| is the size of the ring buffer, which consists of multiple +// packets. In capture devices, the latency relies more on |period_us|, and thus +// one may require more details upon the value implicitly set by ALSA. +MEDIA_EXPORT snd_pcm_t* OpenCaptureDevice(media::AlsaWrapper* wrapper, + const char* device_name, + int channels, + int sample_rate, + snd_pcm_format_t pcm_format, + int buffer_us, + int period_us); snd_pcm_t* OpenPlaybackDevice(media::AlsaWrapper* wrapper, const char* device_name, int channels, int sample_rate, snd_pcm_format_t pcm_format, - int latency_us); + int buffer_us); int CloseDevice(media::AlsaWrapper* wrapper, snd_pcm_t* handle);
diff --git a/media/audio/alsa/alsa_util_unittest.cc b/media/audio/alsa/alsa_util_unittest.cc new file mode 100644 index 0000000..343730d --- /dev/null +++ b/media/audio/alsa/alsa_util_unittest.cc
@@ -0,0 +1,44 @@ +// 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/audio/alsa/alsa_util.h" +#include "media/audio/alsa/mock_alsa_wrapper.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace alsa_util { + +namespace { + +using ::testing::_; +using ::testing::InSequence; +using ::testing::Invoke; +using ::testing::Return; + +} // namespace + +TEST(AlsaUtilTest, FreeHwParams) { + InSequence seq; + media::MockAlsaWrapper mock_alsa_wrapper; + snd_pcm_hw_params_t* params_ptr = (snd_pcm_hw_params_t*)malloc(1); + EXPECT_CALL(mock_alsa_wrapper, PcmOpen(_, _, _, _)).WillOnce(Return(0)); + EXPECT_CALL(mock_alsa_wrapper, PcmSetParams(_, _, _, _, _, _, _)) + .WillOnce(Return(-1)); + EXPECT_CALL(mock_alsa_wrapper, StrError(_)).WillOnce(Return("error")); + EXPECT_CALL(mock_alsa_wrapper, PcmHwParamsMalloc(_)) + .WillOnce(Invoke([params_ptr](snd_pcm_hw_params_t** params) { + *params = params_ptr; + return 0; + })); + EXPECT_CALL(mock_alsa_wrapper, PcmHwParamsAny(_, _)).WillOnce(Return(-1)); + EXPECT_CALL(mock_alsa_wrapper, StrError(_)).WillOnce(Return("error")); + EXPECT_CALL(mock_alsa_wrapper, PcmHwParamsFree(params_ptr)); + EXPECT_CALL(mock_alsa_wrapper, PcmName(_)).WillOnce(Return("default")); + EXPECT_CALL(mock_alsa_wrapper, PcmClose(_)).WillOnce(Return(0)); + snd_pcm_t* handle = OpenCaptureDevice(&mock_alsa_wrapper, "default", 2, 48000, + SND_PCM_FORMAT_S16, 40000, 10000); + EXPECT_EQ(handle, nullptr); + free(params_ptr); +} + +} // namespace alsa_util
diff --git a/media/audio/alsa/alsa_wrapper.cc b/media/audio/alsa/alsa_wrapper.cc index a11a4a4..0696fbe 100644 --- a/media/audio/alsa/alsa_wrapper.cc +++ b/media/audio/alsa/alsa_wrapper.cc
@@ -89,6 +89,121 @@ return snd_pcm_get_params(handle, buffer_size, period_size); } +int AlsaWrapper::PcmHwParamsMalloc(snd_pcm_hw_params_t** hw_params) { + return snd_pcm_hw_params_malloc(hw_params); +} + +int AlsaWrapper::PcmHwParamsAny(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params) { + return snd_pcm_hw_params_any(handle, hw_params); +} + +int AlsaWrapper::PcmHwParamsSetRateResample(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + unsigned int value) { + return snd_pcm_hw_params_set_rate_resample(handle, hw_params, value); +} + +int AlsaWrapper::PcmHwParamsSetRateNear(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + unsigned int* rate, + int* direction) { + return snd_pcm_hw_params_set_rate_near(handle, hw_params, rate, direction); +} + +int AlsaWrapper::PcmHwParamsTestFormat(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + snd_pcm_format_t format) { + return snd_pcm_hw_params_test_format(handle, hw_params, format); +} + +int AlsaWrapper::PcmFormatSize(snd_pcm_format_t format, size_t samples) { + return snd_pcm_format_size(format, samples); +} + +int AlsaWrapper::PcmHwParamsGetChannelsMin(const snd_pcm_hw_params_t* hw_params, + unsigned int* min_channels) { + return snd_pcm_hw_params_get_channels_min(hw_params, min_channels); +} + +int AlsaWrapper::PcmHwParamsGetChannelsMax(const snd_pcm_hw_params_t* hw_params, + unsigned int* max_channels) { + return snd_pcm_hw_params_get_channels_min(hw_params, max_channels); +} + +int AlsaWrapper::PcmHwParamsSetFormat(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + snd_pcm_format_t format) { + return snd_pcm_hw_params_set_format(handle, hw_params, format); +} + +int AlsaWrapper::PcmHwParamsSetAccess(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + snd_pcm_access_t access) { + return snd_pcm_hw_params_set_access(handle, hw_params, access); +} + +int AlsaWrapper::PcmHwParamsSetChannels(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + unsigned int channels) { + return snd_pcm_hw_params_set_channels(handle, hw_params, channels); +} + +int AlsaWrapper::PcmHwParamsSetBufferSizeNear(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + snd_pcm_uframes_t* buffer_size) { + return snd_pcm_hw_params_set_buffer_size_near(handle, hw_params, buffer_size); +} + +int AlsaWrapper::PcmHwParamsSetPeriodSizeNear(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + snd_pcm_uframes_t* period_size, + int* direction) { + return snd_pcm_hw_params_set_period_size_near(handle, hw_params, period_size, + direction); +} + +int AlsaWrapper::PcmHwParams(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params) { + return snd_pcm_hw_params(handle, hw_params); +} + +void AlsaWrapper::PcmHwParamsFree(snd_pcm_hw_params_t* hw_params) { + return snd_pcm_hw_params_free(hw_params); +} + +int AlsaWrapper::PcmSwParamsMalloc(snd_pcm_sw_params_t** sw_params) { + return snd_pcm_sw_params_malloc(sw_params); +} + +int AlsaWrapper::PcmSwParamsCurrent(snd_pcm_t* handle, + snd_pcm_sw_params_t* sw_params) { + return snd_pcm_sw_params_current(handle, sw_params); +} + +int AlsaWrapper::PcmSwParamsSetStartThreshold( + snd_pcm_t* handle, + snd_pcm_sw_params_t* sw_params, + snd_pcm_uframes_t start_threshold) { + return snd_pcm_sw_params_set_start_threshold(handle, sw_params, + start_threshold); +} + +int AlsaWrapper::PcmSwParamsSetAvailMin(snd_pcm_t* handle, + snd_pcm_sw_params_t* sw_params, + snd_pcm_uframes_t period_size) { + return snd_pcm_sw_params_set_avail_min(handle, sw_params, period_size); +} + +int AlsaWrapper::PcmSwParams(snd_pcm_t* handle, + snd_pcm_sw_params_t* sw_params) { + return snd_pcm_sw_params(handle, sw_params); +} + +void AlsaWrapper::PcmSwParamsFree(snd_pcm_sw_params_t* sw_params) { + return snd_pcm_sw_params_free(sw_params); +} + snd_pcm_sframes_t AlsaWrapper::PcmAvailUpdate(snd_pcm_t* handle) { return snd_pcm_avail_update(handle); }
diff --git a/media/audio/alsa/alsa_wrapper.h b/media/audio/alsa/alsa_wrapper.h index bd70f537..6998ca0 100644 --- a/media/audio/alsa/alsa_wrapper.h +++ b/media/audio/alsa/alsa_wrapper.h
@@ -46,6 +46,52 @@ unsigned int latency); virtual int PcmGetParams(snd_pcm_t* handle, snd_pcm_uframes_t* buffer_size, snd_pcm_uframes_t* period_size); + virtual int PcmHwParamsMalloc(snd_pcm_hw_params_t** hw_params); + virtual int PcmHwParamsAny(snd_pcm_t* handle, snd_pcm_hw_params_t* hw_params); + virtual int PcmHwParamsSetRateResample(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + unsigned int value); + virtual int PcmHwParamsSetRateNear(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + unsigned int* rate, + int* direction); + virtual int PcmHwParamsTestFormat(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + snd_pcm_format_t format); + virtual int PcmFormatSize(snd_pcm_format_t format, size_t samples); + virtual int PcmHwParamsGetChannelsMin(const snd_pcm_hw_params_t* hw_params, + unsigned int* min_channels); + virtual int PcmHwParamsGetChannelsMax(const snd_pcm_hw_params_t* hw_params, + unsigned int* max_channels); + virtual int PcmHwParamsSetFormat(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + snd_pcm_format_t format); + virtual int PcmHwParamsSetAccess(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + snd_pcm_access_t access); + virtual int PcmHwParamsSetChannels(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + unsigned int channels); + virtual int PcmHwParamsSetBufferSizeNear(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + snd_pcm_uframes_t* buffer_size); + virtual int PcmHwParamsSetPeriodSizeNear(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + snd_pcm_uframes_t* period_size, + int* direction); + virtual int PcmHwParams(snd_pcm_t* handle, snd_pcm_hw_params_t* hw_params); + virtual void PcmHwParamsFree(snd_pcm_hw_params_t* hw_params); + virtual int PcmSwParamsMalloc(snd_pcm_sw_params_t** sw_params); + virtual int PcmSwParamsCurrent(snd_pcm_t* handle, + snd_pcm_sw_params_t* sw_params); + virtual int PcmSwParamsSetStartThreshold(snd_pcm_t* handle, + snd_pcm_sw_params_t* sw_params, + snd_pcm_uframes_t start_threshold); + virtual int PcmSwParamsSetAvailMin(snd_pcm_t* handle, + snd_pcm_sw_params_t* sw_params, + snd_pcm_uframes_t period_size); + virtual int PcmSwParams(snd_pcm_t* handle, snd_pcm_sw_params_t* sw_params); + virtual void PcmSwParamsFree(snd_pcm_sw_params_t* sw_params); virtual const char* PcmName(snd_pcm_t* handle); virtual snd_pcm_sframes_t PcmAvailUpdate(snd_pcm_t* handle); virtual snd_pcm_state_t PcmState(snd_pcm_t* handle); @@ -105,15 +151,6 @@ virtual const char* StrError(int errnum); - private: - int ConfigureHwParams(snd_pcm_t* handle, - snd_pcm_hw_params_t* hw_params, - snd_pcm_format_t format, - snd_pcm_access_t access, - unsigned int channels, - unsigned int rate, - int soft_resample, - unsigned int latency); DISALLOW_COPY_AND_ASSIGN(AlsaWrapper); };
diff --git a/media/audio/alsa/mock_alsa_wrapper.cc b/media/audio/alsa/mock_alsa_wrapper.cc new file mode 100644 index 0000000..fdb9573 --- /dev/null +++ b/media/audio/alsa/mock_alsa_wrapper.cc
@@ -0,0 +1,13 @@ +// 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/audio/alsa/mock_alsa_wrapper.h" + +namespace media { + +MockAlsaWrapper::MockAlsaWrapper() {} + +MockAlsaWrapper::~MockAlsaWrapper() = default; + +} // namespace media
diff --git a/media/audio/alsa/mock_alsa_wrapper.h b/media/audio/alsa/mock_alsa_wrapper.h new file mode 100644 index 0000000..f4fd16e --- /dev/null +++ b/media/audio/alsa/mock_alsa_wrapper.h
@@ -0,0 +1,188 @@ +// 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 MEDIA_AUDIO_ALSA_MOCK_ALSA_WRAPPER_H_ +#define MEDIA_AUDIO_ALSA_MOCK_ALSA_WRAPPER_H_ + +#include "base/macros.h" +#include "media/audio/alsa/alsa_wrapper.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace media { + +class MockAlsaWrapper : public AlsaWrapper { + public: + MockAlsaWrapper(); + + ~MockAlsaWrapper() override; + + MOCK_METHOD3(DeviceNameHint, int(int card, const char* iface, void*** hints)); + MOCK_METHOD2(DeviceNameGetHint, char*(const void* hint, const char* id)); + MOCK_METHOD1(DeviceNameFreeHint, int(void** hints)); + MOCK_METHOD1(CardNext, int(int* rcard)); + MOCK_METHOD4(PcmOpen, + int(snd_pcm_t** handle, + const char* name, + snd_pcm_stream_t stream, + int mode)); + MOCK_METHOD1(PcmClose, int(snd_pcm_t* handle)); + MOCK_METHOD1(PcmPrepare, int(snd_pcm_t* handle)); + MOCK_METHOD1(PcmDrain, int(snd_pcm_t* handle)); + MOCK_METHOD1(PcmDrop, int(snd_pcm_t* handle)); + MOCK_METHOD2(PcmDelay, int(snd_pcm_t* handle, snd_pcm_sframes_t* delay)); + MOCK_METHOD3(PcmWritei, + snd_pcm_sframes_t(snd_pcm_t* handle, + const void* buffer, + snd_pcm_uframes_t size)); + MOCK_METHOD3(PcmReadi, + snd_pcm_sframes_t(snd_pcm_t* handle, + void* buffer, + snd_pcm_uframes_t size)); + MOCK_METHOD3(PcmRecover, int(snd_pcm_t* handle, int err, int silent)); + MOCK_METHOD7(PcmSetParams, + int(snd_pcm_t* handle, + snd_pcm_format_t format, + snd_pcm_access_t access, + unsigned int channels, + unsigned int rate, + int soft_resample, + unsigned int latency)); + MOCK_METHOD3(PcmGetParams, + int(snd_pcm_t* handle, + snd_pcm_uframes_t* buffer_size, + snd_pcm_uframes_t* period_size)); + MOCK_METHOD1(PcmHwParamsMalloc, int(snd_pcm_hw_params_t** hw_params)); + MOCK_METHOD2(PcmHwParamsAny, + int(snd_pcm_t* handle, snd_pcm_hw_params_t* hw_params)); + MOCK_METHOD3(PcmHwParamsSetRateResample, + int(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + unsigned int value)); + MOCK_METHOD4(PcmHwParamsSetRateNear, + int(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + unsigned int* rate, + int* direction)); + MOCK_METHOD3(PcmHwParamsTestFormat, + int(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + snd_pcm_format_t format)); + MOCK_METHOD2(PcmFormatSize, int(snd_pcm_format_t format, size_t samples)); + MOCK_METHOD2(PcmHwParamsGetChannelsMin, + int(const snd_pcm_hw_params_t* hw_params, + unsigned int* min_channels)); + MOCK_METHOD2(PcmHwParamsGetChannelsMax, + int(const snd_pcm_hw_params_t* hw_params, + unsigned int* max_channels)); + MOCK_METHOD3(PcmHwParamsSetFormat, + int(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + snd_pcm_format_t format)); + MOCK_METHOD3(PcmHwParamsSetAccess, + int(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + snd_pcm_access_t access)); + MOCK_METHOD3(PcmHwParamsSetChannels, + int(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + unsigned int channels)); + MOCK_METHOD3(PcmHwParamsSetBufferSizeNear, + int(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + snd_pcm_uframes_t* buffer_size)); + MOCK_METHOD4(PcmHwParamsSetPeriodSizeNear, + int(snd_pcm_t* handle, + snd_pcm_hw_params_t* hw_params, + snd_pcm_uframes_t* period_size, + int* direction)); + MOCK_METHOD2(PcmHwParams, + int(snd_pcm_t* handle, snd_pcm_hw_params_t* hw_params)); + MOCK_METHOD1(PcmHwParamsFree, void(snd_pcm_hw_params_t* hw_params)); + MOCK_METHOD1(PcmSwParamsMalloc, int(snd_pcm_sw_params_t** sw_params)); + MOCK_METHOD2(PcmSwParamsCurrent, + int(snd_pcm_t* handle, snd_pcm_sw_params_t* sw_params)); + MOCK_METHOD3(PcmSwParamsSetStartThreshold, + int(snd_pcm_t* handle, + snd_pcm_sw_params_t* sw_params, + snd_pcm_uframes_t start_threshold)); + MOCK_METHOD3(PcmSwParamsSetAvailMin, + int(snd_pcm_t* handle, + snd_pcm_sw_params_t* sw_params, + snd_pcm_uframes_t period_size)); + MOCK_METHOD2(PcmSwParams, + int(snd_pcm_t* handle, snd_pcm_sw_params_t* sw_params)); + MOCK_METHOD1(PcmSwParamsFree, void(snd_pcm_sw_params_t* sw_params)); + MOCK_METHOD1(PcmName, const char*(snd_pcm_t* handle)); + MOCK_METHOD1(PcmAvailUpdate, snd_pcm_sframes_t(snd_pcm_t* handle)); + MOCK_METHOD1(PcmState, snd_pcm_state_t(snd_pcm_t* handle)); + MOCK_METHOD1(PcmStart, int(snd_pcm_t* handle)); + MOCK_METHOD2(MixerOpen, int(snd_mixer_t** mixer, int mode)); + MOCK_METHOD2(MixerAttach, int(snd_mixer_t* mixer, const char* name)); + MOCK_METHOD3(MixerElementRegister, + int(snd_mixer_t* mixer, + struct snd_mixer_selem_regopt* options, + snd_mixer_class_t** classp)); + MOCK_METHOD1(MixerFree, void(snd_mixer_t* mixer)); + MOCK_METHOD2(MixerDetach, int(snd_mixer_t* mixer, const char* name)); + MOCK_METHOD1(MixerClose, int(snd_mixer_t* mixer)); + MOCK_METHOD1(MixerLoad, int(snd_mixer_t* mixer)); + MOCK_METHOD1(MixerFirstElem, snd_mixer_elem_t*(snd_mixer_t* mixer)); + MOCK_METHOD1(MixerNextElem, snd_mixer_elem_t*(snd_mixer_elem_t* elem)); + MOCK_METHOD1(MixerSelemIsActive, int(snd_mixer_elem_t* elem)); + MOCK_METHOD1(MixerSelemName, const char*(snd_mixer_elem_t* elem)); + MOCK_METHOD2(MixerSelemSetCaptureVolumeAll, + int(snd_mixer_elem_t* elem, long value)); + MOCK_METHOD3(MixerSelemGetCaptureVolume, + int(snd_mixer_elem_t* elem, + snd_mixer_selem_channel_id_t channel, + long* value)); + MOCK_METHOD1(MixerSelemHasCaptureVolume, int(snd_mixer_elem_t* elem)); + MOCK_METHOD3(MixerSelemGetCaptureVolumeRange, + int(snd_mixer_elem_t* elem, long* min, long* max)); + MOCK_METHOD1(MixerElemGetCallbackPrivate, void*(const snd_mixer_elem_t* obj)); + MOCK_METHOD2(MixerElemSetCallback, + void(snd_mixer_elem_t* obj, snd_mixer_elem_callback_t val)); + MOCK_METHOD2(MixerElemSetCallbackPrivate, + void(snd_mixer_elem_t* obj, void* val)); + MOCK_METHOD2(MixerFindSelem, + snd_mixer_elem_t*(snd_mixer_t* mixer, + const snd_mixer_selem_id_t* id)); + MOCK_METHOD1(MixerHandleEvents, int(snd_mixer_t* mixer)); + MOCK_METHOD3(MixerPollDescriptors, + int(snd_mixer_t* mixer, + struct pollfd* pfds, + unsigned int space)); + MOCK_METHOD1(MixerPollDescriptorsCount, int(snd_mixer_t* mixer)); + MOCK_METHOD3(MixerSelemGetPlaybackSwitch, + int(snd_mixer_elem_t* elem, + snd_mixer_selem_channel_id_t channel, + int* value)); + MOCK_METHOD3(MixerSelemGetPlaybackVolume, + int(snd_mixer_elem_t* elem, + snd_mixer_selem_channel_id_t channel, + long* value)); + MOCK_METHOD3(MixerSelemGetPlaybackVolumeRange, + int(snd_mixer_elem_t* elem, long* min, long* max)); + MOCK_METHOD1(MixerSelemHasPlaybackSwitch, int(snd_mixer_elem_t* elem)); + MOCK_METHOD2(MixerSelemIdSetIndex, + void(snd_mixer_selem_id_t* obj, unsigned int val)); + MOCK_METHOD2(MixerSelemIdSetName, + void(snd_mixer_selem_id_t* obj, const char* val)); + MOCK_METHOD3(MixerSelemSetPlaybackSwitch, + int(snd_mixer_elem_t* elem, + snd_mixer_selem_channel_id_t channel, + int value)); + MOCK_METHOD2(MixerSelemSetPlaybackVolumeAll, + int(snd_mixer_elem_t* elem, long value)); + MOCK_METHOD1(MixerSelemIdMalloc, int(snd_mixer_selem_id_t** ptr)); + MOCK_METHOD1(MixerSelemIdFree, void(snd_mixer_selem_id_t* obj)); + MOCK_METHOD1(StrError, const char*(int errnum)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockAlsaWrapper); +}; + +} // namespace media + +#endif // MEDIA_AUDIO_ALSA_MOCK_ALSA_WRAPPER_H_
diff --git a/media/audio/audio_device_description.cc b/media/audio/audio_device_description.cc index ebca4a61..87f8f37d 100644 --- a/media/audio/audio_device_description.cc +++ b/media/audio/audio_device_description.cc
@@ -56,6 +56,8 @@ std::string AudioDeviceDescription::GetCommunicationsDeviceName() { #if defined(OS_WIN) return GetLocalizedStringUTF8(COMMUNICATIONS_AUDIO_DEVICE_NAME); +#elif defined(IS_CHROMECAST) + return ""; #else NOTREACHED(); return "";
diff --git a/media/audio/audio_input_device.cc b/media/audio/audio_input_device.cc index 30e45646..f2ed25e 100644 --- a/media/audio/audio_input_device.cc +++ b/media/audio/audio_input_device.cc
@@ -165,7 +165,7 @@ // audio_thread_.reset(). In most cases, the thread will already be stopped. // // |alive_checker_| must outlive |audio_callback_|. - base::ScopedAllowBlocking allow_blocking; + base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_thread_join; audio_thread_.reset(); audio_callback_.reset(); alive_checker_.reset();
diff --git a/media/audio/audio_output_device.cc b/media/audio/audio_output_device.cc index b298f7a..0cf6975 100644 --- a/media/audio/audio_output_device.cc +++ b/media/audio/audio_output_device.cc
@@ -256,7 +256,7 @@ // in which case, we cannot use the message loop to close the thread handle // and can't rely on the main thread existing either. base::AutoLock auto_lock_(audio_thread_lock_); - base::ThreadRestrictions::ScopedAllowIO allow_io; + base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_thread_join; audio_thread_.reset(); audio_callback_.reset(); stopping_hack_ = false;
diff --git a/media/base/android/media_codec_loop.cc b/media/base/android/media_codec_loop.cc index bf8418a..94f49f0 100644 --- a/media/base/android/media_codec_loop.cc +++ b/media/base/android/media_codec_loop.cc
@@ -234,6 +234,7 @@ // to send in nullptr for the source. Note that the client doesn't // guarantee that the pointer will remain valid after we return anyway. pending_input_buf_data_.memory = nullptr; + client_->OnWaiting(WaitingReason::kNoDecryptionKey); SetState(STATE_WAITING_FOR_KEY); // Do not call OnInputDataQueued yet. break;
diff --git a/media/base/android/media_codec_loop.h b/media/base/android/media_codec_loop.h index 8b5924ed..4791db0 100644 --- a/media/base/android/media_codec_loop.h +++ b/media/base/android/media_codec_loop.h
@@ -21,6 +21,7 @@ #include "media/base/encryption_scheme.h" #include "media/base/media_export.h" #include "media/base/subsample_entry.h" +#include "media/base/waiting.h" // MediaCodecLoop is based on Android's MediaCodec API. // The MediaCodec API is required to play encrypted (as in EME) content on @@ -184,6 +185,9 @@ // If this returns false, then we transition to STATE_ERROR. virtual bool OnDecodedFrame(const OutputBuffer& out) = 0; + // Notify the client when waiting for |reason|, e.g. STATE_WAITING_FOR_KEY. + virtual void OnWaiting(WaitingReason reason) = 0; + // Processes the output format change on |media_codec|. Returns true on // success, or false to transition to the error state. virtual bool OnOutputFormatChanged() = 0;
diff --git a/media/base/android/media_codec_loop_unittest.cc b/media/base/android/media_codec_loop_unittest.cc index d257535a..1e2eb8c 100644 --- a/media/base/android/media_codec_loop_unittest.cc +++ b/media/base/android/media_codec_loop_unittest.cc
@@ -11,6 +11,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "media/base/android/media_codec_bridge.h" #include "media/base/android/mock_media_codec_bridge.h" +#include "media/base/waiting.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -35,6 +36,7 @@ MOCK_METHOD1(OnInputDataQueued, void(bool)); MOCK_METHOD1(OnDecodedEos, bool(const MediaCodecLoop::OutputBuffer&)); MOCK_METHOD1(OnDecodedFrame, bool(const MediaCodecLoop::OutputBuffer&)); + MOCK_METHOD1(OnWaiting, void(WaitingReason reason)); MOCK_METHOD0(OnOutputFormatChanged, bool()); MOCK_METHOD0(OnCodecLoopError, void()); }; @@ -449,6 +451,8 @@ // Notify MCL that it's missing the key. ExpectQueueInputBuffer(input_buffer_index, data, MEDIA_CODEC_NO_KEY); + EXPECT_CALL(*client_, OnWaiting(WaitingReason::kNoDecryptionKey)).Times(1); + // MCL should now try for output buffers. ExpectDequeueOutputBuffer(MEDIA_CODEC_TRY_AGAIN_LATER);
diff --git a/media/base/decoder_buffer.h b/media/base/decoder_buffer.h index 3239282..20f2b41 100644 --- a/media/base/decoder_buffer.h +++ b/media/base/decoder_buffer.h
@@ -147,6 +147,8 @@ discard_padding_ = discard_padding; } + // Returns DecryptConfig associated with |this|. Returns null iff |this| is + // not encrypted. const DecryptConfig* decrypt_config() const { DCHECK(!end_of_stream()); return decrypt_config_.get();
diff --git a/media/filters/android/media_codec_audio_decoder.cc b/media/filters/android/media_codec_audio_decoder.cc index 316237df1..8f08efa 100644 --- a/media/filters/android/media_codec_audio_decoder.cc +++ b/media/filters/android/media_codec_audio_decoder.cc
@@ -64,9 +64,11 @@ CdmContext* cdm_context, const InitCB& init_cb, const OutputCB& output_cb, - const WaitingCB& /* waiting_cb */) { + const WaitingCB& waiting_cb) { DVLOG(1) << __func__ << ": " << config.AsHumanReadableString(); DCHECK_NE(state_, STATE_WAITING_FOR_MEDIA_CRYPTO); + DCHECK(output_cb); + DCHECK(waiting_cb); // Initialization and reinitialization should not be called during pending // decode. @@ -103,7 +105,11 @@ } config_ = config; + + // TODO(xhwang): Check whether BindToCurrentLoop is needed here. output_cb_ = BindToCurrentLoop(output_cb); + waiting_cb_ = BindToCurrentLoop(waiting_cb); + SetInitialConfiguration(); if (config_.is_encrypted() && !media_crypto_) { @@ -465,6 +471,11 @@ return true; } +void MediaCodecAudioDecoder::OnWaiting(WaitingReason reason) { + DVLOG(2) << __func__; + waiting_cb_.Run(reason); +} + bool MediaCodecAudioDecoder::OnOutputFormatChanged() { DVLOG(2) << __func__; MediaCodecBridge* media_codec = codec_loop_->GetCodec();
diff --git a/media/filters/android/media_codec_audio_decoder.h b/media/filters/android/media_codec_audio_decoder.h index 5fc8292..923b3f7 100644 --- a/media/filters/android/media_codec_audio_decoder.h +++ b/media/filters/android/media_codec_audio_decoder.h
@@ -100,6 +100,7 @@ void OnInputDataQueued(bool) override; bool OnDecodedEos(const MediaCodecLoop::OutputBuffer& out) override; bool OnDecodedFrame(const MediaCodecLoop::OutputBuffer& out) override; + void OnWaiting(WaitingReason reason) override; bool OnOutputFormatChanged() override; void OnCodecLoopError() override; @@ -187,6 +188,8 @@ // Callback that delivers output frames. OutputCB output_cb_; + WaitingCB waiting_cb_; + std::unique_ptr<MediaCodecLoop> codec_loop_; std::unique_ptr<AudioTimestampHelper> timestamp_helper_;
diff --git a/media/filters/audio_decoder_unittest.cc b/media/filters/audio_decoder_unittest.cc index 9b373fd..c43b115 100644 --- a/media/filters/audio_decoder_unittest.cc +++ b/media/filters/audio_decoder_unittest.cc
@@ -247,7 +247,7 @@ decoder_->Initialize( config, nullptr, NewExpectedBoolCB(success), base::Bind(&AudioDecoderTest::OnDecoderOutput, base::Unretained(this)), - base::NullCallback()); + base::DoNothing()); base::RunLoop().RunUntilIdle(); }
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn index 5e64accd..6384fc3b 100644 --- a/media/gpu/BUILD.gn +++ b/media/gpu/BUILD.gn
@@ -435,6 +435,8 @@ "android/fake_codec_allocator.h", "android/image_reader_gl_owner_unittest.cc", "android/media_codec_video_decoder_unittest.cc", + "android/mock_abstract_texture.cc", + "android/mock_abstract_texture.h", "android/mock_android_video_surface_chooser.cc", "android/mock_android_video_surface_chooser.h", "android/mock_device_info.cc",
diff --git a/media/gpu/accelerated_video_decoder.h b/media/gpu/accelerated_video_decoder.h index fb7acd82..ee9dc93 100644 --- a/media/gpu/accelerated_video_decoder.h +++ b/media/gpu/accelerated_video_decoder.h
@@ -66,13 +66,11 @@ // we need a new set of them, or when an error occurs. virtual DecodeResult Decode() WARN_UNUSED_RESULT = 0; - // Return dimensions/required number of pictures that client should be ready - // to provide for the decoder to function properly (of which up to - // GetNumReferenceFrames() might be needed for internal decoding). To be used - // after Decode() returns kAllocateNewSurfaces. + // Return dimensions/required number of output surfaces that client should + // be ready to provide for the decoder to function properly. + // To be used after Decode() returns kAllocateNewSurfaces. virtual gfx::Size GetPicSize() const = 0; virtual size_t GetRequiredNumOfPictures() const = 0; - virtual size_t GetNumReferenceFrames() const = 0; // About 3 secs for 30 fps video. When the new sized keyframe is missed, the // decoder cannot decode the frame. The number of frames are skipped until
diff --git a/media/gpu/android/android_video_decode_accelerator.cc b/media/gpu/android/android_video_decode_accelerator.cc index 329c3f3..64ad14d6 100644 --- a/media/gpu/android/android_video_decode_accelerator.cc +++ b/media/gpu/android/android_video_decode_accelerator.cc
@@ -264,6 +264,7 @@ const MakeGLContextCurrentCallback& make_context_current_cb, const GetContextGroupCallback& get_context_group_cb, const AndroidOverlayMojoFactoryCB& overlay_factory_cb, + const CreateAbstractTextureCallback& create_abstract_texture_cb, DeviceInfo* device_info) : client_(nullptr), codec_allocator_(codec_allocator), @@ -289,6 +290,7 @@ force_defer_surface_creation_for_testing_(false), force_allow_software_decoding_for_testing_(false), overlay_factory_cb_(overlay_factory_cb), + create_abstract_texture_cb_(create_abstract_texture_cb), weak_this_factory_(this) {} AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { @@ -1391,6 +1393,19 @@ return get_context_group_cb_.Run(); } +std::unique_ptr<gpu::gles2::AbstractTexture> +AndroidVideoDecodeAccelerator::CreateAbstractTexture(GLenum target, + GLenum internal_format, + GLsizei width, + GLsizei height, + GLsizei depth, + int border, + GLenum format, + GLenum type) { + return create_abstract_texture_cb_.Run(target, internal_format, width, height, + depth, border, format, type); +} + void AndroidVideoDecodeAccelerator::OnStopUsingOverlayImmediately( AndroidOverlay* overlay) { DVLOG(1) << __func__;
diff --git a/media/gpu/android/android_video_decode_accelerator.h b/media/gpu/android/android_video_decode_accelerator.h index 2b88e96..5fc9bd4c 100644 --- a/media/gpu/android/android_video_decode_accelerator.h +++ b/media/gpu/android/android_video_decode_accelerator.h
@@ -55,6 +55,7 @@ const MakeGLContextCurrentCallback& make_context_current_cb, const GetContextGroupCallback& get_context_group_cb, const AndroidOverlayMojoFactoryCB& overlay_factory_cb, + const CreateAbstractTextureCallback& create_abstract_texture_cb, DeviceInfo* device_info); ~AndroidVideoDecodeAccelerator() override; @@ -76,6 +77,15 @@ // AVDAStateProvider implementation: const gfx::Size& GetSize() const override; gpu::gles2::ContextGroup* GetContextGroup() const override; + std::unique_ptr<gpu::gles2::AbstractTexture> CreateAbstractTexture( + GLenum target, + GLenum internal_format, + GLsizei width, + GLsizei height, + GLsizei depth, + int border, + GLenum format, + GLenum type) override; // Notifies the client about the error and sets |state_| to |ERROR|. If we're // in the middle of Initialize, we guarantee that Initialize will return // failure. If deferred init is pending, then we'll fail deferred init. @@ -394,6 +404,8 @@ // Optional factory to produce mojo AndroidOverlay instances. AndroidOverlayMojoFactoryCB overlay_factory_cb_; + CreateAbstractTextureCallback create_abstract_texture_cb_; + std::unique_ptr<PromotionHintAggregator> promotion_hint_aggregator_; // Update |cached_frame_information_|.
diff --git a/media/gpu/android/android_video_decode_accelerator_unittest.cc b/media/gpu/android/android_video_decode_accelerator_unittest.cc index 984f9bf..df548c2 100644 --- a/media/gpu/android/android_video_decode_accelerator_unittest.cc +++ b/media/gpu/android/android_video_decode_accelerator_unittest.cc
@@ -29,6 +29,7 @@ #include "media/gpu/android/android_video_surface_chooser.h" #include "media/gpu/android/codec_allocator.h" #include "media/gpu/android/fake_codec_allocator.h" +#include "media/gpu/android/mock_abstract_texture.h" #include "media/gpu/android/mock_android_video_surface_chooser.h" #include "media/gpu/android/mock_device_info.h" #include "media/media_buildflags.h" @@ -148,6 +149,9 @@ base::BindRepeating(&GetContextGroup, context_group_), base::BindRepeating(&AndroidVideoDecodeAcceleratorTest::OverlayFactory, base::Unretained(this)), + base::BindRepeating( + &AndroidVideoDecodeAcceleratorTest::CreateAbstractTexture, + base::Unretained(this)), device_info_.get()); vda_.reset(avda); avda->force_defer_surface_creation_for_testing_ = @@ -159,6 +163,18 @@ return result; } + std::unique_ptr<gpu::gles2::AbstractTexture> CreateAbstractTexture( + GLenum target, + GLenum internal_format, + GLsizei width, + GLsizei height, + GLsizei depth, + int border, + GLenum format, + GLenum type) { + return std::make_unique<MockAbstractTexture>(0); + } + // Initialize |vda_|, providing a new surface for it. You may get the surface // by asking |codec_allocator_|. void InitializeAVDAWithOverlay() {
diff --git a/media/gpu/android/avda_picture_buffer_manager.cc b/media/gpu/android/avda_picture_buffer_manager.cc index e68b23f..e6c97ee 100644 --- a/media/gpu/android/avda_picture_buffer_manager.cc +++ b/media/gpu/android/avda_picture_buffer_manager.cc
@@ -54,7 +54,16 @@ if (!surface_bundle->overlay) { // Create the texture owner. - texture_owner_ = TextureOwner::Create(); + // TODO(liberato): Don't memorize this. However, since this entire path is + // deprecated, it's probably okay. + std::unique_ptr<gpu::gles2::AbstractTexture> texture = + state_provider_->CreateAbstractTexture(GL_TEXTURE_EXTERNAL_OES, GL_RGBA, + 0, // width, + 0, // height + 1, // depth + 0, // border + GL_RGBA, GL_UNSIGNED_BYTE); + texture_owner_ = TextureOwner::Create(std::move(texture)); if (!texture_owner_) return false;
diff --git a/media/gpu/android/avda_state_provider.h b/media/gpu/android/avda_state_provider.h index 93d5ef78..4ae1dde 100644 --- a/media/gpu/android/avda_state_provider.h +++ b/media/gpu/android/avda_state_provider.h
@@ -26,6 +26,15 @@ // Various handy getters. virtual const gfx::Size& GetSize() const = 0; virtual gpu::gles2::ContextGroup* GetContextGroup() const = 0; + virtual std::unique_ptr<gpu::gles2::AbstractTexture> CreateAbstractTexture( + GLenum target, + GLenum internal_format, + GLsizei width, + GLsizei height, + GLsizei depth, + int border, + GLenum format, + GLenum type) = 0; // Report a fatal error. This will post NotifyError(), and transition to the // error state.
diff --git a/media/gpu/android/codec_image_unittest.cc b/media/gpu/android/codec_image_unittest.cc index b928929..061b190 100644 --- a/media/gpu/android/codec_image_unittest.cc +++ b/media/gpu/android/codec_image_unittest.cc
@@ -14,6 +14,7 @@ #include "media/base/android/media_codec_bridge.h" #include "media/base/android/mock_media_codec_bridge.h" #include "media/gpu/android/codec_image.h" +#include "media/gpu/android/mock_abstract_texture.h" #include "media/gpu/android/mock_texture_owner.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -56,15 +57,17 @@ context_->Initialize(surface_.get(), gl::GLContextAttribs()); ASSERT_TRUE(context_->MakeCurrent(surface_.get())); - GLuint texture_id = 0; - glGenTextures(1, &texture_id); + glGenTextures(1, &texture_id_); // The tests rely on this texture being bound. - glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id); - texture_owner_ = new NiceMock<MockTextureOwner>(texture_id, context_.get(), + glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id_); + + texture_owner_ = new NiceMock<MockTextureOwner>(texture_id_, context_.get(), surface_.get()); } void TearDown() override { + if (texture_id_ && context_->MakeCurrent(surface_.get())) + glDeleteTextures(1, &texture_id_); context_ = nullptr; share_group_ = nullptr; surface_ = nullptr; @@ -94,6 +97,7 @@ scoped_refptr<gl::GLContext> context_; scoped_refptr<gl::GLShareGroup> share_group_; scoped_refptr<gl::GLSurface> surface_; + GLuint texture_id_ = 0; class PromotionHintReceiver { public:
diff --git a/media/gpu/android/image_reader_gl_owner.cc b/media/gpu/android/image_reader_gl_owner.cc index a519e693..94f02eac 100644 --- a/media/gpu/android/image_reader_gl_owner.cc +++ b/media/gpu/android/image_reader_gl_owner.cc
@@ -16,6 +16,7 @@ #include "base/posix/eintr_wrapper.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread_task_runner_handle.h" +#include "gpu/command_buffer/service/abstract_texture.h" #include "gpu/ipc/common/android/android_image_reader_utils.h" #include "ui/gl/gl_fence_android_native_fence_sync.h" #include "ui/gl/scoped_binders.h" @@ -66,9 +67,10 @@ AImage* image_; }; -ImageReaderGLOwner::ImageReaderGLOwner(GLuint texture_id) - : current_image_(nullptr), - texture_id_(texture_id), +ImageReaderGLOwner::ImageReaderGLOwner( + std::unique_ptr<gpu::gles2::AbstractTexture> texture) + : TextureOwner(std::move(texture)), + current_image_(nullptr), loader_(base::android::AndroidImageReader::GetInstance()), context_(gl::GLContext::GetCurrent()), surface_(gl::GLSurface::GetCurrent()), @@ -120,9 +122,25 @@ ImageReaderGLOwner::~ImageReaderGLOwner() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK(image_reader_); DCHECK_EQ(external_image_refs_.size(), 0u); + // Clear the texture before we return, so that it can OnTextureDestroyed() if + // it hasn't already. This will do nothing if it has already been destroyed. + ClearAbstractTexture(); +} + +void ImageReaderGLOwner::OnTextureDestroyed(gpu::gles2::AbstractTexture*) { + // The AbstractTexture is being destroyed. This can happen if, for example, + // the video decoder's gl context is lost. Remember that the platform texture + // might not be gone; it's possible for the gl decoder (and AbstractTexture) + // to be destroyed via, e.g., renderer crash, but the platform texture is + // still shared with some other gl context. + + // This should only be called once. Note that even during construction, + // there's a check that |image_reader_| is constructed. Otherwise, errors + // during init might cause us to get here without an image reader. + DCHECK(image_reader_); + // Now we can stop listening to new images. loader_.AImageReader_setImageListener(image_reader_, NULL); @@ -132,25 +150,20 @@ // Delete the image reader. loader_.AImageReader_delete(image_reader_); - - // Delete texture - ui::ScopedMakeCurrent scoped_make_current(context_.get(), surface_.get()); - if (context_->IsCurrent(surface_.get())) { - glDeleteTextures(1, &texture_id_); - DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); - } -} - -GLuint ImageReaderGLOwner::GetTextureId() const { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - return texture_id_; + image_reader_ = nullptr; } gl::ScopedJavaSurface ImageReaderGLOwner::CreateJavaSurface() const { + // If we've already lost the texture, then do nothing. + if (!image_reader_) { + DLOG(ERROR) << "Already lost texture / image reader"; + return gl::ScopedJavaSurface::AcquireExternalSurface(nullptr); + } + // Get the android native window from the image reader. ANativeWindow* window = nullptr; if (loader_.AImageReader_getWindow(image_reader_, &window) != AMEDIA_OK) { - LOG(ERROR) << "unable to get a window from image reader."; + DLOG(ERROR) << "unable to get a window from image reader."; return gl::ScopedJavaSurface::AcquireExternalSurface(nullptr); } @@ -165,6 +178,11 @@ void ImageReaderGLOwner::UpdateTexImage() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + // If we've lost the texture, then do nothing. + if (!texture()) + return; + DCHECK(image_reader_); // Acquire the latest image asynchronously @@ -241,7 +259,7 @@ return; // Create EGL image from the AImage and bind it to the texture. - if (!gpu::CreateAndBindEglImage(current_image_, texture_id_, &loader_)) + if (!gpu::CreateAndBindEglImage(current_image_, GetTextureId(), &loader_)) return; current_image_bound_ = true;
diff --git a/media/gpu/android/image_reader_gl_owner.h b/media/gpu/android/image_reader_gl_owner.h index 7fc0ad6..897624e 100644 --- a/media/gpu/android/image_reader_gl_owner.h +++ b/media/gpu/android/image_reader_gl_owner.h
@@ -25,7 +25,6 @@ // data present in the surface. class MEDIA_GPU_EXPORT ImageReaderGLOwner : public TextureOwner { public: - GLuint GetTextureId() const override; gl::GLContext* GetContext() const override; gl::GLSurface* GetSurface() const override; gl::ScopedJavaSurface CreateJavaSurface() const override; @@ -39,12 +38,15 @@ std::unique_ptr<gl::GLImage::ScopedHardwareBuffer> GetAHardwareBuffer() override; + protected: + void OnTextureDestroyed(gpu::gles2::AbstractTexture*) override; + private: friend class TextureOwner; class ScopedHardwareBufferImpl; - ImageReaderGLOwner(GLuint texture_id); + ImageReaderGLOwner(std::unique_ptr<gpu::gles2::AbstractTexture> texture); ~ImageReaderGLOwner() override; // Deletes the current image if it has no pending refs. Returns false on @@ -61,7 +63,6 @@ // image until next new image is acquired which overwrites this. AImage* current_image_; base::ScopedFD current_image_fence_; - GLuint texture_id_; std::unique_ptr<AImageReader_ImageListener> listener_; // Set to true if the current image is bound to |texture_id_|.
diff --git a/media/gpu/android/image_reader_gl_owner_unittest.cc b/media/gpu/android/image_reader_gl_owner_unittest.cc index b03177d8..d30aeb6 100644 --- a/media/gpu/android/image_reader_gl_owner_unittest.cc +++ b/media/gpu/android/image_reader_gl_owner_unittest.cc
@@ -9,7 +9,9 @@ #include "base/message_loop/message_loop.h" #include "base/test/scoped_feature_list.h" +#include "gpu/command_buffer/service/abstract_texture.h" #include "media/base/media_switches.h" +#include "media/gpu/android/mock_abstract_texture.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context_egl.h" @@ -36,10 +38,18 @@ context_->Initialize(surface_.get(), gl::GLContextAttribs()); ASSERT_TRUE(context_->MakeCurrent(surface_.get())); - image_reader_ = TextureOwner::Create(); + // Create a texture. + glGenTextures(1, &texture_id_); + + std::unique_ptr<MockAbstractTexture> texture = + std::make_unique<MockAbstractTexture>(texture_id_); + abstract_texture_ = texture->AsWeakPtr(); + image_reader_ = TextureOwner::Create(std::move(texture)); } void TearDown() override { + if (texture_id_ && context_->MakeCurrent(surface_.get())) + glDeleteTextures(1, &texture_id_); image_reader_ = nullptr; context_ = nullptr; share_group_ = nullptr; @@ -51,6 +61,8 @@ scoped_refptr<TextureOwner> image_reader_; GLuint texture_id_ = 0; + base::WeakPtr<MockAbstractTexture> abstract_texture_; + scoped_refptr<gl::GLContext> context_; scoped_refptr<gl::GLShareGroup> share_group_; scoped_refptr<gl::GLSurface> surface_; @@ -71,7 +83,7 @@ TEST_F(ImageReaderGLOwnerTest, GLTextureIsCreatedAndDestroyed) { // |texture_id| should not work anymore after we delete image_reader_. image_reader_ = nullptr; - ASSERT_FALSE(glIsTexture(texture_id_)); + EXPECT_FALSE(abstract_texture_); } // Make sure that image_reader_ remembers the correct context and surface. @@ -93,7 +105,7 @@ ASSERT_TRUE(new_context->MakeCurrent(new_surface.get())); image_reader_ = nullptr; - ASSERT_FALSE(glIsTexture(texture_id_)); + EXPECT_FALSE(abstract_texture_); // |new_context| should still be current. ASSERT_TRUE(new_context->IsCurrent(new_surface.get()));
diff --git a/media/gpu/android/media_codec_video_decoder.cc b/media/gpu/android/media_codec_video_decoder.cc index 531284a1..6a1b9839 100644 --- a/media/gpu/android/media_codec_video_decoder.cc +++ b/media/gpu/android/media_codec_video_decoder.cc
@@ -188,7 +188,10 @@ CdmContext* cdm_context, const InitCB& init_cb, const OutputCB& output_cb, - const WaitingCB& /* waiting_cb */) { + const WaitingCB& waiting_cb) { + DCHECK(output_cb); + DCHECK(waiting_cb); + const bool first_init = !decoder_config_.IsValidConfig(); DVLOG(1) << (first_init ? "Initializing" : "Reinitializing") << " MCVD with config: " << config.AsHumanReadableString() @@ -211,6 +214,7 @@ surface_chooser_helper_.SetVideoRotation(decoder_config_.video_rotation()); output_cb_ = output_cb; + waiting_cb_ = waiting_cb; #if BUILDFLAG(USE_PROPRIETARY_CODECS) if (config.codec() == kCodecH264) @@ -657,6 +661,7 @@ case CodecWrapper::QueueStatus::kNoKey: // Retry when a key is added. waiting_for_key_ = true; + waiting_cb_.Run(WaitingReason::kNoDecryptionKey); return false; case CodecWrapper::QueueStatus::kError: EnterTerminalState(State::kError);
diff --git a/media/gpu/android/media_codec_video_decoder.h b/media/gpu/android/media_codec_video_decoder.h index bed9eb50..39dd102 100644 --- a/media/gpu/android/media_codec_video_decoder.h +++ b/media/gpu/android/media_codec_video_decoder.h
@@ -225,9 +225,10 @@ // The EOS decode cb for an EOS currently being processed by the codec. Called // when the EOS is output. - VideoDecoder::DecodeCB eos_decode_cb_; + DecodeCB eos_decode_cb_; - VideoDecoder::OutputCB output_cb_; + OutputCB output_cb_; + WaitingCB waiting_cb_; VideoDecoderConfig decoder_config_; // Codec specific data (SPS and PPS for H264). Some MediaCodecs initialize
diff --git a/media/gpu/android/media_codec_video_decoder_unittest.cc b/media/gpu/android/media_codec_video_decoder_unittest.cc index 013ecf5..1f09e9c 100644 --- a/media/gpu/android/media_codec_video_decoder_unittest.cc +++ b/media/gpu/android/media_codec_video_decoder_unittest.cc
@@ -183,7 +183,7 @@ auto init_cb = [](bool* result_out, bool result) { *result_out = result; }; mcvd_->Initialize(config, false, cdm_.get(), base::Bind(init_cb, &result), base::BindRepeating(&OutputCb, &most_recent_frame_), - base::NullCallback()); + base::DoNothing()); base::RunLoop().RunUntilIdle(); // If there is a CDM available, then we expect that MCVD will be waiting
diff --git a/media/gpu/android/mock_abstract_texture.cc b/media/gpu/android/mock_abstract_texture.cc new file mode 100644 index 0000000..2adda1f --- /dev/null +++ b/media/gpu/android/mock_abstract_texture.cc
@@ -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. + +#include "media/gpu/android/mock_abstract_texture.h" + +namespace media { + +MockAbstractTexture::MockAbstractTexture() = default; + +MockAbstractTexture::MockAbstractTexture(GLuint service_id) + : texture_base_(std::make_unique<gpu::TextureBase>(service_id)) { + ON_CALL(*this, GetTextureBase()) + .WillByDefault(::testing::Return(texture_base_.get())); +} + +MockAbstractTexture::~MockAbstractTexture() = default; + +} // namespace media
diff --git a/media/gpu/android/mock_abstract_texture.h b/media/gpu/android/mock_abstract_texture.h new file mode 100644 index 0000000..737c95f9 --- /dev/null +++ b/media/gpu/android/mock_abstract_texture.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 MEDIA_GPU_ANDROID_MOCK_ABSTRACT_TEXTURE_H_ +#define MEDIA_GPU_ANDROID_MOCK_ABSTRACT_TEXTURE_H_ + +#include "base/memory/weak_ptr.h" +#include "gpu/command_buffer/service/abstract_texture.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace media { + +// SupportsWeakPtr so it's easy to tell when it has been destroyed. +class MockAbstractTexture + : public ::testing::NiceMock<gpu::gles2::AbstractTexture>, + public base::SupportsWeakPtr<MockAbstractTexture> { + public: + MockAbstractTexture(); + // If provided, we'll make a TextureBase that returns this id. We do not + // delete this texture. + explicit MockAbstractTexture(GLuint service_id); + ~MockAbstractTexture() override; + + MOCK_METHOD0(ForceContextLost, void()); + MOCK_CONST_METHOD0(GetTextureBase, gpu::TextureBase*()); + MOCK_METHOD2(SetParameteri, void(GLenum pname, GLint param)); + MOCK_METHOD2(BindStreamTextureImage, + void(gpu::gles2::GLStreamTextureImage* image, + GLuint service_id)); + MOCK_METHOD2(BindImage, void(gl::GLImage* image, bool client_managed)); + MOCK_METHOD0(ReleaseImage, void()); + MOCK_CONST_METHOD0(GetImage, gl::GLImage*()); + MOCK_METHOD0(SetCleared, void()); + MOCK_METHOD1(SetCleanupCallback, void(CleanupCallback)); + + private: + // May be null. + std::unique_ptr<gpu::TextureBase> texture_base_; + CleanupCallback cleanup_callback_; +}; + +} // namespace media + +#endif // MEDIA_GPU_ANDROID_MOCK_ABSTRACT_TEXTURE_H_
diff --git a/media/gpu/android/mock_texture_owner.cc b/media/gpu/android/mock_texture_owner.cc index bd1368b..9cb0b23 100644 --- a/media/gpu/android/mock_texture_owner.cc +++ b/media/gpu/android/mock_texture_owner.cc
@@ -4,6 +4,8 @@ #include "media/gpu/android/mock_texture_owner.h" +#include "media/gpu/android/mock_abstract_texture.h" + namespace media { using testing::Invoke; @@ -12,7 +14,7 @@ MockTextureOwner::MockTextureOwner(GLuint fake_texture_id, gl::GLContext* fake_context, gl::GLSurface* fake_surface) - : fake_texture_id(fake_texture_id), + : TextureOwner(std::make_unique<MockAbstractTexture>(fake_texture_id)), fake_context(fake_context), fake_surface(fake_surface), expecting_frame_available(false) { @@ -31,6 +33,9 @@ Invoke(this, &MockTextureOwner::FakeWaitForFrameAvailable)); } -MockTextureOwner::~MockTextureOwner() = default; +MockTextureOwner::~MockTextureOwner() { + // TextureOwner requires this. + ClearAbstractTexture(); +} } // namespace media
diff --git a/media/gpu/android/mock_texture_owner.h b/media/gpu/android/mock_texture_owner.h index 04756f6..71d7e61 100644 --- a/media/gpu/android/mock_texture_owner.h +++ b/media/gpu/android/mock_texture_owner.h
@@ -32,6 +32,7 @@ MOCK_METHOD0(IgnorePendingRelease, void()); MOCK_METHOD0(IsExpectingFrameAvailable, bool()); MOCK_METHOD0(WaitForFrameAvailable, void()); + MOCK_METHOD1(OnTextureDestroyed, void(gpu::gles2::AbstractTexture*)); std::unique_ptr<gl::GLImage::ScopedHardwareBuffer> GetAHardwareBuffer() override { @@ -45,7 +46,6 @@ bool FakeIsExpectingFrameAvailable() { return expecting_frame_available; } void FakeWaitForFrameAvailable() { expecting_frame_available = false; } - GLuint fake_texture_id; gl::GLContext* fake_context; gl::GLSurface* fake_surface; bool expecting_frame_available;
diff --git a/media/gpu/android/surface_texture_gl_owner.cc b/media/gpu/android/surface_texture_gl_owner.cc index 9590589..c6a25dd0 100644 --- a/media/gpu/android/surface_texture_gl_owner.cc +++ b/media/gpu/android/surface_texture_gl_owner.cc
@@ -9,6 +9,7 @@ #include "base/metrics/histogram_macros.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread_task_runner_handle.h" +#include "gpu/command_buffer/service/abstract_texture.h" #include "ui/gl/scoped_binders.h" #include "ui/gl/scoped_make_current.h" @@ -30,9 +31,10 @@ ~FrameAvailableEvent() = default; }; -SurfaceTextureGLOwner::SurfaceTextureGLOwner(GLuint texture_id) - : surface_texture_(gl::SurfaceTexture::Create(texture_id)), - texture_id_(texture_id), +SurfaceTextureGLOwner::SurfaceTextureGLOwner( + std::unique_ptr<gpu::gles2::AbstractTexture> texture) + : TextureOwner(std::move(texture)), + surface_texture_(gl::SurfaceTexture::Create(GetTextureId())), context_(gl::GLContext::GetCurrent()), surface_(gl::GLSurface::GetCurrent()), frame_available_event_(new FrameAvailableEvent()) { @@ -45,47 +47,43 @@ SurfaceTextureGLOwner::~SurfaceTextureGLOwner() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - // Make sure that the SurfaceTexture isn't using the GL objects. - surface_texture_ = nullptr; - - std::unique_ptr<ui::ScopedMakeCurrent> scoped_make_current; - - // If the context is current, skip ScopedMakeCurrent to prevent (a) a - // potentially heavyweight virtual context switch and (b) a potential crash - // during stub destruction (https://crbug.com/839605). - if (!context_->IsCurrent(nullptr)) { - scoped_make_current = - std::make_unique<ui::ScopedMakeCurrent>(context_.get(), surface_.get()); - if (!context_->IsCurrent(surface_.get())) - return; - } - - glDeleteTextures(1, &texture_id_); - DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + // Clear the texture before we return, so that it can OnTextureDestroyed() if + // it hasn't already. + ClearAbstractTexture(); } -GLuint SurfaceTextureGLOwner::GetTextureId() const { +void SurfaceTextureGLOwner::OnTextureDestroyed(gpu::gles2::AbstractTexture*) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - return texture_id_; + + // Make sure that the SurfaceTexture isn't using the GL objects. + surface_texture_ = nullptr; } gl::ScopedJavaSurface SurfaceTextureGLOwner::CreateJavaSurface() const { + // |surface_texture_| might be null, but that's okay. return gl::ScopedJavaSurface(surface_texture_.get()); } void SurfaceTextureGLOwner::UpdateTexImage() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - surface_texture_->UpdateTexImage(); + if (surface_texture_) + surface_texture_->UpdateTexImage(); } void SurfaceTextureGLOwner::GetTransformMatrix(float mtx[]) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - surface_texture_->GetTransformMatrix(mtx); + // If we don't have a SurfaceTexture, then the matrix doesn't matter. We + // still initialize it for good measure. + if (surface_texture_) + surface_texture_->GetTransformMatrix(mtx); + else + memset(mtx, 0, sizeof(mtx[0]) * 16); } void SurfaceTextureGLOwner::ReleaseBackBuffers() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - surface_texture_->ReleaseBackBuffers(); + if (surface_texture_) + surface_texture_->ReleaseBackBuffers(); } gl::GLContext* SurfaceTextureGLOwner::GetContext() const {
diff --git a/media/gpu/android/surface_texture_gl_owner.h b/media/gpu/android/surface_texture_gl_owner.h index d01b49f..a96ed6df 100644 --- a/media/gpu/android/surface_texture_gl_owner.h +++ b/media/gpu/android/surface_texture_gl_owner.h
@@ -24,7 +24,6 @@ // present in the surface. class MEDIA_GPU_EXPORT SurfaceTextureGLOwner : public TextureOwner { public: - GLuint GetTextureId() const override; gl::GLContext* GetContext() const override; gl::GLSurface* GetSurface() const override; gl::ScopedJavaSurface CreateJavaSurface() const override; @@ -38,10 +37,13 @@ std::unique_ptr<gl::GLImage::ScopedHardwareBuffer> GetAHardwareBuffer() override; + protected: + void OnTextureDestroyed(gpu::gles2::AbstractTexture*) override; + private: friend class TextureOwner; - SurfaceTextureGLOwner(GLuint texture_id); + SurfaceTextureGLOwner(std::unique_ptr<gpu::gles2::AbstractTexture> texture); ~SurfaceTextureGLOwner() override; scoped_refptr<gl::SurfaceTexture> surface_texture_;
diff --git a/media/gpu/android/surface_texture_gl_owner_unittest.cc b/media/gpu/android/surface_texture_gl_owner_unittest.cc index 39b2da8..15a8143 100644 --- a/media/gpu/android/surface_texture_gl_owner_unittest.cc +++ b/media/gpu/android/surface_texture_gl_owner_unittest.cc
@@ -11,6 +11,7 @@ #include "base/bind.h" #include "base/logging.h" #include "base/message_loop/message_loop.h" +#include "media/gpu/android/mock_abstract_texture.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_bindings.h" @@ -43,16 +44,20 @@ context_->Initialize(surface_.get(), gl::GLContextAttribs()); ASSERT_TRUE(context_->MakeCurrent(surface_.get())); - surface_texture_ = SurfaceTextureGLOwner::Create(); + // Create a texture. + glGenTextures(1, &texture_id_); + + std::unique_ptr<MockAbstractTexture> texture = + std::make_unique<MockAbstractTexture>(texture_id_); + abstract_texture_ = texture->AsWeakPtr(); + surface_texture_ = SurfaceTextureGLOwner::Create(std::move(texture)); texture_id_ = surface_texture_->GetTextureId(); - // Bind and un-bind the texture, since that's required for glIsTexture to - // return true. - glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id_); - glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0); - ASSERT_TRUE(glIsTexture(texture_id_)); + EXPECT_TRUE(abstract_texture_); } void TearDown() override { + if (texture_id_ && context_->MakeCurrent(surface_.get())) + glDeleteTextures(1, &texture_id_); surface_texture_ = nullptr; context_ = nullptr; share_group_ = nullptr; @@ -63,24 +68,31 @@ scoped_refptr<TextureOwner> surface_texture_; GLuint texture_id_ = 0; + base::WeakPtr<MockAbstractTexture> abstract_texture_; + scoped_refptr<gl::GLContext> context_; scoped_refptr<gl::GLShareGroup> share_group_; scoped_refptr<gl::GLSurface> surface_; base::MessageLoop message_loop_; }; +TEST_F(SurfaceTextureGLOwnerTest, OwnerReturnsServiceId) { + // The owner should give us back the same service id we provided. + EXPECT_EQ(texture_id_, surface_texture_->GetTextureId()); +} + // Verify that SurfaceTextureGLOwner creates a bindable GL texture, and deletes // it during destruction. TEST_F(SurfaceTextureGLOwnerTest, GLTextureIsCreatedAndDestroyed) { // |texture_id| should not work anymore after we delete |surface_texture|. surface_texture_ = nullptr; - ASSERT_FALSE(glIsTexture(texture_id_)); + EXPECT_FALSE(abstract_texture_); } // Calling ReleaseBackBuffers shouldn't deallocate the texture handle. TEST_F(SurfaceTextureGLOwnerTest, ReleaseDoesntDestroyTexture) { surface_texture_->ReleaseBackBuffers(); - ASSERT_TRUE(glIsTexture(texture_id_)); + EXPECT_TRUE(abstract_texture_); } // Make sure that |surface_texture_| remembers the correct context and surface. @@ -102,7 +114,7 @@ ASSERT_TRUE(new_context->MakeCurrent(new_surface.get())); surface_texture_ = nullptr; - ASSERT_FALSE(glIsTexture(texture_id_)); + EXPECT_FALSE(abstract_texture_); // |new_context| should still be current. ASSERT_TRUE(new_context->IsCurrent(new_surface.get()));
diff --git a/media/gpu/android/texture_owner.cc b/media/gpu/android/texture_owner.cc index c6a6e73..b2e4a62a 100644 --- a/media/gpu/android/texture_owner.cc +++ b/media/gpu/android/texture_owner.cc
@@ -7,6 +7,8 @@ #include "base/android/android_image_reader_compat.h" #include "base/feature_list.h" #include "base/threading/thread_task_runner_handle.h" +#include "gpu/command_buffer/service/abstract_texture.h" +#include "gpu/command_buffer/service/decoder_context.h" #include "media/base/media_switches.h" #include "media/gpu/android/image_reader_gl_owner.h" #include "media/gpu/android/surface_texture_gl_owner.h" @@ -14,36 +16,60 @@ namespace media { -TextureOwner::TextureOwner() +TextureOwner::TextureOwner(std::unique_ptr<gpu::gles2::AbstractTexture> texture) : base::RefCountedDeleteOnSequence<TextureOwner>( base::ThreadTaskRunnerHandle::Get()), - task_runner_(base::ThreadTaskRunnerHandle::Get()) {} + texture_(std::move(texture)), + task_runner_(base::ThreadTaskRunnerHandle::Get()) { + // Notify the subclass when the texture is destroyed. + // Unretained is safe, since we insist that |texture_| is dropped before we're + // destroyed, which implies that the callback has run. + texture_->SetCleanupCallback(base::BindOnce(&TextureOwner::OnTextureDestroyed, + base::Unretained(this))); +} -TextureOwner::~TextureOwner() = default; +TextureOwner::~TextureOwner() { + // The subclass must delete the texture before now. + DCHECK(!texture_); +} -scoped_refptr<TextureOwner> TextureOwner::Create() { - GLuint texture_id; - glGenTextures(1, &texture_id); - if (!texture_id) - return nullptr; - +// static +scoped_refptr<TextureOwner> TextureOwner::Create( + std::unique_ptr<gpu::gles2::AbstractTexture> texture) { // Set the parameters on the texture. - gl::ScopedActiveTexture active_texture(GL_TEXTURE0); - gl::ScopedTextureBinder texture_binder(GL_TEXTURE_EXTERNAL_OES, texture_id); - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + texture->SetParameteri(GL_TEXTURE_MAG_FILTER, GL_LINEAR); + texture->SetParameteri(GL_TEXTURE_MIN_FILTER, GL_LINEAR); + texture->SetParameteri(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + texture->SetParameteri(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // If AImageReader is supported and is enabled by media flag, use it. if (base::android::AndroidImageReader::GetInstance().IsSupported() && base::FeatureList::IsEnabled(media::kAImageReaderVideoOutput)) { - return new ImageReaderGLOwner(texture_id); + return new ImageReaderGLOwner(std::move(texture)); } // If not, fall back to legacy path. - return new SurfaceTextureGLOwner(texture_id); + return new SurfaceTextureGLOwner(std::move(texture)); +} + +// static +std::unique_ptr<gpu::gles2::AbstractTexture> TextureOwner::CreateTexture( + gpu::DecoderContext* decoder) { + // Note that the size isn't really used. We just care about the service id. + return decoder->CreateAbstractTexture(GL_TEXTURE_EXTERNAL_OES, GL_RGBA, + 0, // width + 0, // height + 1, // depth + 0, // border + GL_RGBA, GL_UNSIGNED_BYTE); +} + +GLuint TextureOwner::GetTextureId() const { + return texture_->service_id(); +} + +void TextureOwner::ClearAbstractTexture() { + texture_.reset(); } } // namespace media
diff --git a/media/gpu/android/texture_owner.h b/media/gpu/android/texture_owner.h index 5bbf383..0dcba7b7 100644 --- a/media/gpu/android/texture_owner.h +++ b/media/gpu/android/texture_owner.h
@@ -17,6 +17,13 @@ #include "ui/gl/gl_image.h" #include "ui/gl/gl_surface.h" +namespace gpu { +class DecoderContext; +namespace gles2 { +class AbstractTexture; +} // namespace gles2 +} // namespace gpu + namespace media { // A Texture wrapper interface that creates and maintains ownership of the @@ -30,16 +37,21 @@ public: // Creates a GL texture using the current platform GL context and returns a // new TextureOwner attached to it. Returns null on failure. - static scoped_refptr<TextureOwner> Create(); + // |texture| should be either from CreateAbstractTexture() or a mock. The + // corresponding GL context must be current. + static scoped_refptr<TextureOwner> Create( + std::unique_ptr<gpu::gles2::AbstractTexture> texture); - TextureOwner(); + // Create a texture that's appropriate for a TextureOwner. + static std::unique_ptr<gpu::gles2::AbstractTexture> CreateTexture( + gpu::DecoderContext* decoder); scoped_refptr<base::SingleThreadTaskRunner> task_runner() { return task_runner_; } // Returns the GL texture id that the TextureOwner is attached to. - virtual GLuint GetTextureId() const = 0; + GLuint GetTextureId() const; virtual gl::GLContext* GetContext() const = 0; virtual gl::GLSurface* GetSurface() const = 0; @@ -81,9 +93,26 @@ protected: friend class base::RefCountedDeleteOnSequence<TextureOwner>; friend class base::DeleteHelper<TextureOwner>; + + // |texture| is the texture that we'll own. + TextureOwner(std::unique_ptr<gpu::gles2::AbstractTexture> texture); virtual ~TextureOwner(); + // Drop |texture_| immediately. Will call OnTextureDestroyed immediately if + // it hasn't been called before (e.g., due to lost context). + // Subclasses must call this before they complete destruction, else + // OnTextureDestroyed might be called when we drop |texture_|, which is not + // defined once subclass destruction has completed. + void ClearAbstractTexture(); + + // Called when |texture_| signals that the platform texture will be destroyed. + // See AbstractTexture::SetCleanupCallback. + virtual void OnTextureDestroyed(gpu::gles2::AbstractTexture*) = 0; + + gpu::gles2::AbstractTexture* texture() const { return texture_.get(); } + private: + std::unique_ptr<gpu::gles2::AbstractTexture> texture_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; DISALLOW_COPY_AND_ASSIGN(TextureOwner);
diff --git a/media/gpu/android/texture_pool_unittest.cc b/media/gpu/android/texture_pool_unittest.cc index 762b6e99..b294ff2 100644 --- a/media/gpu/android/texture_pool_unittest.cc +++ b/media/gpu/android/texture_pool_unittest.cc
@@ -6,7 +6,6 @@ #include <memory> -#include "base/memory/weak_ptr.h" #include "base/run_loop.h" #include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" @@ -15,6 +14,7 @@ #include "gpu/command_buffer/service/abstract_texture.h" #include "gpu/command_buffer/service/sequence_id.h" #include "gpu/ipc/common/gpu_messages.h" +#include "media/gpu/android/mock_abstract_texture.h" #include "media/gpu/fake_command_buffer_helper.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -26,26 +26,6 @@ using testing::NiceMock; using testing::Return; -// SupportsWeakPtr so it's easy to tell when it has been destroyed. -class MockAbstractTexture : public NiceMock<AbstractTexture>, - public base::SupportsWeakPtr<MockAbstractTexture> { - public: - MockAbstractTexture() {} - ~MockAbstractTexture() override {} - - MOCK_METHOD0(ForceContextLost, void()); - MOCK_CONST_METHOD0(GetTextureBase, gpu::TextureBase*()); - MOCK_METHOD2(SetParameteri, void(GLenum pname, GLint param)); - MOCK_METHOD2(BindStreamTextureImage, - void(gpu::gles2::GLStreamTextureImage* image, - GLuint service_id)); - MOCK_METHOD2(BindImage, void(gl::GLImage* image, bool client_managed)); - MOCK_METHOD0(ReleaseImage, void()); - MOCK_CONST_METHOD0(GetImage, gl::GLImage*()); - MOCK_METHOD0(SetCleared, void()); - MOCK_METHOD1(SetCleanupCallback, void(CleanupCallback)); -}; - class TexturePoolTest : public testing::Test { public: void SetUp() override {
diff --git a/media/gpu/android/video_frame_factory_impl.cc b/media/gpu/android/video_frame_factory_impl.cc index 083fc296..cd242863 100644 --- a/media/gpu/android/video_frame_factory_impl.cc +++ b/media/gpu/android/video_frame_factory_impl.cc
@@ -145,7 +145,9 @@ texture_pool_ = new TexturePool(CommandBufferHelper::Create(stub_)); decoder_helper_ = GLES2DecoderHelper::Create(stub_->decoder_context()); - return TextureOwner::Create(); + + return TextureOwner::Create( + TextureOwner::CreateTexture(stub_->decoder_context())); } void GpuVideoFrameFactory::CreateVideoFrame(
diff --git a/media/gpu/gpu_video_decode_accelerator_factory.cc b/media/gpu/gpu_video_decode_accelerator_factory.cc index 67ba4da..27b3fe4e 100644 --- a/media/gpu/gpu_video_decode_accelerator_factory.cc +++ b/media/gpu/gpu_video_decode_accelerator_factory.cc
@@ -98,7 +98,8 @@ const BindGLImageCallback& bind_image_cb) { return base::WrapUnique(new GpuVideoDecodeAcceleratorFactory( get_gl_context_cb, make_context_current_cb, bind_image_cb, - GetContextGroupCallback(), AndroidOverlayMojoFactoryCB())); + GetContextGroupCallback(), AndroidOverlayMojoFactoryCB(), + CreateAbstractTextureCallback())); } // static @@ -108,10 +109,11 @@ const MakeGLContextCurrentCallback& make_context_current_cb, const BindGLImageCallback& bind_image_cb, const GetContextGroupCallback& get_context_group_cb, - const AndroidOverlayMojoFactoryCB& overlay_factory_cb) { + const AndroidOverlayMojoFactoryCB& overlay_factory_cb, + const CreateAbstractTextureCallback& create_abstract_texture_cb) { return base::WrapUnique(new GpuVideoDecodeAcceleratorFactory( get_gl_context_cb, make_context_current_cb, bind_image_cb, - get_context_group_cb, overlay_factory_cb)); + get_context_group_cb, overlay_factory_cb, create_abstract_texture_cb)); } // static @@ -270,7 +272,7 @@ std::make_unique<AndroidVideoSurfaceChooserImpl>( DeviceInfo::GetInstance()->IsSetOutputSurfaceSupported()), make_context_current_cb_, get_context_group_cb_, overlay_factory_cb_, - DeviceInfo::GetInstance())); + create_abstract_texture_cb_, DeviceInfo::GetInstance())); return decoder; } #endif @@ -280,12 +282,14 @@ const MakeGLContextCurrentCallback& make_context_current_cb, const BindGLImageCallback& bind_image_cb, const GetContextGroupCallback& get_context_group_cb, - const AndroidOverlayMojoFactoryCB& overlay_factory_cb) + const AndroidOverlayMojoFactoryCB& overlay_factory_cb, + const CreateAbstractTextureCallback& create_abstract_texture_cb) : get_gl_context_cb_(get_gl_context_cb), make_context_current_cb_(make_context_current_cb), bind_image_cb_(bind_image_cb), get_context_group_cb_(get_context_group_cb), - overlay_factory_cb_(overlay_factory_cb) {} + overlay_factory_cb_(overlay_factory_cb), + create_abstract_texture_cb_(create_abstract_texture_cb) {} GpuVideoDecodeAcceleratorFactory::~GpuVideoDecodeAcceleratorFactory() = default;
diff --git a/media/gpu/gpu_video_decode_accelerator_factory.h b/media/gpu/gpu_video_decode_accelerator_factory.h index 3c94bdc..74f10eb 100644 --- a/media/gpu/gpu_video_decode_accelerator_factory.h +++ b/media/gpu/gpu_video_decode_accelerator_factory.h
@@ -14,6 +14,7 @@ #include "gpu/config/gpu_preferences.h" #include "media/base/android_overlay_mojo_factory.h" #include "media/gpu/buildflags.h" +#include "media/gpu/gpu_video_decode_accelerator_helpers.h" #include "media/gpu/media_gpu_export.h" #include "media/video/video_decode_accelerator.h" @@ -70,7 +71,8 @@ const MakeGLContextCurrentCallback& make_context_current_cb, const BindGLImageCallback& bind_image_cb, const GetContextGroupCallback& get_context_group_cb, - const AndroidOverlayMojoFactoryCB& overlay_factory_cb); + const AndroidOverlayMojoFactoryCB& overlay_factory_cb, + const CreateAbstractTextureCallback& create_abstract_texture_cb); static std::unique_ptr<GpuVideoDecodeAcceleratorFactory> CreateWithNoGL(); @@ -91,7 +93,8 @@ const MakeGLContextCurrentCallback& make_context_current_cb, const BindGLImageCallback& bind_image_cb, const GetContextGroupCallback& get_context_group_cb, - const AndroidOverlayMojoFactoryCB& overlay_factory_cb); + const AndroidOverlayMojoFactoryCB& overlay_factory_cb, + const CreateAbstractTextureCallback& create_abstract_texture_cb); #if defined(OS_WIN) std::unique_ptr<VideoDecodeAccelerator> CreateD3D11VDA( @@ -137,6 +140,7 @@ const BindGLImageCallback bind_image_cb_; const GetContextGroupCallback get_context_group_cb_; const AndroidOverlayMojoFactoryCB overlay_factory_cb_; + const CreateAbstractTextureCallback create_abstract_texture_cb_; base::ThreadChecker thread_checker_;
diff --git a/media/gpu/gpu_video_decode_accelerator_helpers.h b/media/gpu/gpu_video_decode_accelerator_helpers.h index 02573bd..8de9ed40 100644 --- a/media/gpu/gpu_video_decode_accelerator_helpers.h +++ b/media/gpu/gpu_video_decode_accelerator_helpers.h
@@ -15,6 +15,7 @@ namespace gpu { namespace gles2 { +class AbstractTexture; class ContextGroup; } } @@ -51,6 +52,18 @@ using GetContextGroupCallback = base::RepeatingCallback<gpu::gles2::ContextGroup*(void)>; +// Create and return an AbstractTexture, if possible. +using CreateAbstractTextureCallback = + base::RepeatingCallback<std::unique_ptr<gpu::gles2::AbstractTexture>( + unsigned /* GLenum */ target, + unsigned /* GLenum */ internal_format, + int /* GLsizei */ width, + int /* GLsizei */ height, + int /* GLsizei */ depth, + int /* GLint */ border, + unsigned /* GLenum */ format, + unsigned /* GLenum */ type)>; + } // namespace media #endif // MEDIA_GPU_GPU_VIDEO_DECODE_ACCELERATOR_HELPERS_H_
diff --git a/media/gpu/h264_decoder.cc b/media/gpu/h264_decoder.cc index ad814d19..9effde4 100644 --- a/media/gpu/h264_decoder.cc +++ b/media/gpu/h264_decoder.cc
@@ -1445,17 +1445,7 @@ } size_t H264Decoder::GetRequiredNumOfPictures() const { - constexpr size_t kPicsInPipeline = limits::kMaxVideoFrames + 1; - return GetNumReferenceFrames() + kPicsInPipeline; -} - -size_t H264Decoder::GetNumReferenceFrames() const { - // Use the maximum number of pictures in the Decoded Picture Buffer plus one - // for the one being currently egressed. - // Another +1 is experimentally needed for high-to-high resolution changes. - // TODO(mcasas): Figure out why +2 instead of +1, see crbug.com/909926 and - // http://crrev.com/c/1363807/9/media/gpu/h264_decoder.cc#1449. - return dpb_.max_num_pics() + 2; + return dpb_.max_num_pics() + kPicsInPipeline; } // static
diff --git a/media/gpu/h264_decoder.h b/media/gpu/h264_decoder.h index e77ede18..a7b9e4b 100644 --- a/media/gpu/h264_decoder.h +++ b/media/gpu/h264_decoder.h
@@ -168,7 +168,6 @@ DecodeResult Decode() override WARN_UNUSED_RESULT; gfx::Size GetPicSize() const override; size_t GetRequiredNumOfPictures() const override; - size_t GetNumReferenceFrames() const override; // Return true if we need to start a new picture. static bool IsNewPrimaryCodedPicture(const H264Picture* curr_pic, @@ -183,6 +182,17 @@ H264Picture* pic); private: + // We need to keep at most kDPBMaxSize pictures in DPB for + // reference/to display later and an additional one for the one currently + // being decoded. We also ask for some additional ones since VDA needs + // to accumulate a few ready-to-output pictures before it actually starts + // displaying and giving them back. +2 instead of +1 because of subjective + // smoothness improvement during testing. + enum { + kPicsInPipeline = limits::kMaxVideoFrames + 2, + kMaxNumReqPictures = H264DPB::kDPBMaxSize + kPicsInPipeline, + }; + // Internal state of the decoder. enum State { // After initialization, need an SPS.
diff --git a/media/gpu/ipc/service/gpu_video_decode_accelerator.cc b/media/gpu/ipc/service/gpu_video_decode_accelerator.cc index f668142..9ee74f9 100644 --- a/media/gpu/ipc/service/gpu_video_decode_accelerator.cc +++ b/media/gpu/ipc/service/gpu_video_decode_accelerator.cc
@@ -84,6 +84,25 @@ return stub->context_group().get(); } +static std::unique_ptr<gpu::gles2::AbstractTexture> CreateAbstractTexture( + const base::WeakPtr<gpu::CommandBufferStub>& stub, + GLenum target, + GLenum internal_format, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type) { + if (!stub) { + DLOG(ERROR) << "Stub is gone; no DecoderContext."; + return nullptr; + } + + return stub->decoder_context()->CreateAbstractTexture( + target, internal_format, width, height, depth, border, format, type); +} + } // anonymous namespace // DebugAutoLock works like AutoLock but only acquires the lock when @@ -168,6 +187,8 @@ bind_image_cb_ = base::BindRepeating(&BindImage, stub_->AsWeakPtr()); get_context_group_cb_ = base::BindRepeating(&GetContextGroup, stub_->AsWeakPtr()); + create_abstract_texture_cb_ = + base::BindRepeating(&CreateAbstractTexture, stub_->AsWeakPtr()); } GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { @@ -352,7 +373,8 @@ std::unique_ptr<GpuVideoDecodeAcceleratorFactory> vda_factory = GpuVideoDecodeAcceleratorFactory::CreateWithGLES2Decoder( get_gl_context_cb_, make_context_current_cb_, bind_image_cb_, - get_context_group_cb_, overlay_factory_cb_); + get_context_group_cb_, overlay_factory_cb_, + create_abstract_texture_cb_); if (!vda_factory) { LOG(ERROR) << "Failed creating the VDA factory";
diff --git a/media/gpu/ipc/service/gpu_video_decode_accelerator.h b/media/gpu/ipc/service/gpu_video_decode_accelerator.h index c8ebc6f1..d3b652e 100644 --- a/media/gpu/ipc/service/gpu_video_decode_accelerator.h +++ b/media/gpu/ipc/service/gpu_video_decode_accelerator.h
@@ -130,6 +130,9 @@ // Callback to return a ContextGroup*. GetContextGroupCallback get_context_group_cb_; + // Callback to return a DecoderContext*. + CreateAbstractTextureCallback create_abstract_texture_cb_; + // The texture dimensions as requested by ProvidePictureBuffers(). gfx::Size texture_dimensions_;
diff --git a/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc b/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc index 7b1794f..6153aed 100644 --- a/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc +++ b/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc
@@ -143,12 +143,12 @@ size_t max_coded_buffer_size = VaapiJpegEncoder::GetMaxCodedBufferSize(input_size); if (max_coded_buffer_size > cached_output_buffer_size_) { - vaapi_wrapper_->DestroyCodedBuffers(); + vaapi_wrapper_->DestroyVABuffers(); cached_output_buffer_size_ = 0; VABufferID output_buffer_id; - if (!vaapi_wrapper_->CreateCodedBuffer(max_coded_buffer_size, - &output_buffer_id)) { + if (!vaapi_wrapper_->CreateVABuffer(max_coded_buffer_size, + &output_buffer_id)) { VLOGF(1) << "Failed to create VA buffer for encoding output"; notify_error_cb_.Run(buffer_id, PLATFORM_FAILURE); return; @@ -179,10 +179,10 @@ return; } - // Get the encoded output. DownloadFromCodedBuffer() is a blocking call. It + // Get the encoded output. DownloadFromVABuffer() is a blocking call. It // would wait until encoding is finished. size_t encoded_size = 0; - if (!vaapi_wrapper_->DownloadFromCodedBuffer( + if (!vaapi_wrapper_->DownloadFromVABuffer( cached_output_buffer_id_, va_surface_id_, static_cast<uint8_t*>(request->output_shm->memory()), request->output_shm->size(), &encoded_size)) {
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc index 1441727d..1dfbf111 100644 --- a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc +++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
@@ -16,7 +16,6 @@ #include "base/logging.h" #include "base/macros.h" #include "base/metrics/histogram_macros.h" -#include "base/numerics/ranges.h" #include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/synchronization/waitable_event.h" @@ -48,6 +47,7 @@ // UMA errors that the VaapiVideoDecodeAccelerator class reports. enum VAVDADecoderFailure { VAAPI_ERROR = 0, + VAAPI_VPP_ERROR = 1, VAVDA_DECODER_FAILURES_MAX, }; @@ -95,12 +95,15 @@ cpuid.model() >= kGeminiLakeModelId; return is_geminilake_or_later; } + // Decides if the current platform and profile may decode using the client's // PictureBuffers, or engage the Vpp to adapt VaApi's and the client's format. -bool ShouldDecodeOnclientPictureBuffers(VideoCodecProfile profile, - bool has_va_surface_ids = true) { - return has_va_surface_ids && (profile == VP9PROFILE_PROFILE0) && - (IsKabyLakeOrLater() || IsGeminiLakeOrLater()); +bool ShouldDecodeOnclientPictureBuffers( + VideoDecodeAccelerator::Config::OutputMode output_mode, + VideoCodecProfile profile) { + return output_mode == VideoDecodeAccelerator::Config::OutputMode::ALLOCATE && + (IsKabyLakeOrLater() || IsGeminiLakeOrLater()) && + profile == VP9PROFILE_PROFILE0; } } // namespace @@ -169,7 +172,6 @@ : state_(kUninitialized), input_ready_(&lock_), vaapi_picture_factory_(new VaapiPictureFactory()), - profile_(VIDEO_CODEC_PROFILE_UNKNOWN), surfaces_available_(&lock_), decode_using_client_picture_buffers_(false), task_runner_(base::ThreadTaskRunnerHandle::Get()), @@ -177,8 +179,7 @@ finish_flush_pending_(false), awaiting_va_surfaces_recycle_(false), requested_num_pics_(0), - requested_num_reference_frames_(0), - previously_requested_num_reference_frames_(0), + profile_(VIDEO_CODEC_PROFILE_UNKNOWN), make_context_current_cb_(make_context_current_cb), bind_image_cb_(bind_image_cb), weak_this_factory_(this) { @@ -240,13 +241,15 @@ VLOGF(1) << "Unsupported profile " << GetProfileName(profile); return false; } - profile_ = profile; CHECK(decoder_thread_.Start()); decoder_thread_task_runner_ = decoder_thread_.task_runner(); state_ = kIdle; + profile_ = profile; output_mode_ = config.output_mode; + decode_using_client_picture_buffers_ = + ShouldDecodeOnclientPictureBuffers(output_mode_, profile_); return true; } @@ -291,12 +294,9 @@ PLATFORM_FAILURE, ); } - { - base::AutoLock auto_lock(lock_); - TRACE_COUNTER_ID2("media,gpu", "Vaapi frames at client", this, "used", - pictures_.size() - available_picture_buffers_.size(), - "available", available_picture_buffers_.size()); - } + TRACE_COUNTER_ID2("media,gpu", "Vaapi frames at client", this, "used", + pictures_.size() - available_picture_buffers_.size(), + "available", available_picture_buffers_.size()); DVLOGF(4) << "Notifying output picture id " << output_id << " for input " << input_id @@ -317,11 +317,8 @@ if (!client_) return; - { - base::AutoLock auto_lock(lock_); - if (pending_output_cbs_.empty() || available_picture_buffers_.empty()) - return; - } + if (pending_output_cbs_.empty() || available_picture_buffers_.empty()) + return; auto output_cb = std::move(pending_output_cbs_.front()); pending_output_cbs_.pop(); @@ -475,8 +472,7 @@ FROM_HERE, base::Bind(&VaapiVideoDecodeAccelerator::InitiateSurfaceSetChange, weak_this_, decoder_->GetRequiredNumOfPictures(), - decoder_->GetPicSize(), - decoder_->GetNumReferenceFrames())); + decoder_->GetPicSize())); // We'll get rescheduled once ProvidePictureBuffers() finishes. return; @@ -513,37 +509,23 @@ } } -void VaapiVideoDecodeAccelerator::InitiateSurfaceSetChange( - size_t num_pics, - gfx::Size size, - size_t num_reference_frames) { +void VaapiVideoDecodeAccelerator::InitiateSurfaceSetChange(size_t num_pics, + gfx::Size size) { DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(!awaiting_va_surfaces_recycle_); - DCHECK_GT(num_pics, num_reference_frames); // At this point decoder has stopped running and has already posted onto our // loop any remaining output request callbacks, which executed before we got - // here. Some of them might have been pended though, because we might not have - // had enough PictureBuffers to output surfaces to. Initiate a wait cycle, + // here. Some of them might have been pended though, because we might not + // have had enough TFPictures to output surfaces to. Initiate a wait cycle, // which will wait for client to return enough PictureBuffers to us, so that // we can finish all pending output callbacks, releasing associated surfaces. + VLOGF(2) << "Initiating surface set change"; awaiting_va_surfaces_recycle_ = true; + requested_num_pics_ = num_pics; requested_pic_size_ = size; - // If we cannot |decode_using_client_picture_buffers_|, split the requested - // |num_pics| between VA reference frames and client PictureBuffers proper. - if (ShouldDecodeOnclientPictureBuffers(profile_)) - requested_num_reference_frames_ = 0; - else - requested_num_reference_frames_ = num_reference_frames; - - requested_num_pics_ = num_pics - requested_num_reference_frames_; - - VLOGF(2) << " |requested_num_pics_| = " << requested_num_pics_ - << "; |requested_num_reference_frames_| = " - << requested_num_reference_frames_; - TryFinishSurfaceSetChange(); } @@ -553,20 +535,14 @@ if (!awaiting_va_surfaces_recycle_) return; - base::AutoLock auto_lock(lock_); - const size_t kExpectedMaxAvailableVASurfaces = - decode_using_client_picture_buffers_ - ? pictures_.size() - : previously_requested_num_reference_frames_; - if (!pending_output_cbs_.empty() || - kExpectedMaxAvailableVASurfaces != available_va_surfaces_.size()) { - // If we're here the stream resolution has changed; we need to wait until: - // - all |pending_output_cbs_| have been executed - // - all VASurfaces are back to |available_va_surfaces_|; we can't use - // |requested_num_reference_frames_| for comparison, since it might have - // changed in the previous call to InitiateSurfaceSetChange(), so we use - // |previously_requested_num_reference_frames_| instead. + pictures_.size() != available_va_surfaces_.size()) { + // Either: + // 1. Not all pending pending output callbacks have been executed yet. + // Wait for the client to return enough pictures and retry later. + // 2. The above happened and all surface release callbacks have been posted + // as the result, but not all have executed yet. Post ourselves after them + // to let them release surfaces. DVLOGF(2) << "Awaiting pending output/surface release callbacks to finish"; task_runner_->PostTask( FROM_HERE, @@ -575,8 +551,6 @@ return; } - previously_requested_num_reference_frames_ = requested_num_reference_frames_; - // All surfaces released, destroy them and dismiss all PictureBuffers. awaiting_va_surfaces_recycle_ = false; available_va_surfaces_.clear(); @@ -593,14 +567,13 @@ VLOGF(2) << "Requesting " << requested_num_pics_ << " pictures of size: " << requested_pic_size_.ToString(); - const VideoPixelFormat format = GfxBufferFormatToVideoPixelFormat( + VideoPixelFormat format = GfxBufferFormatToVideoPixelFormat( vaapi_picture_factory_->GetBufferFormat()); task_runner_->PostTask( FROM_HERE, base::BindOnce(&Client::ProvidePictureBuffers, client_, requested_num_pics_, format, 1, requested_pic_size_, vaapi_picture_factory_->GetGLTextureTarget())); - // |client_| may respond via AssignPictureBuffers(). } void VaapiVideoDecodeAccelerator::Decode( @@ -645,11 +618,29 @@ const unsigned int va_format = GetVaFormatForVideoCodecProfile(profile_); std::vector<VASurfaceID> va_surface_ids; + // If we can't |decode_using_client_picture_buffers_|, we have to allocate a + // |vpp_vaapi_wrapper_| for VaapiPicture to DownloadFromSurface() the VA's + // internal decoded frame. + if (!decode_using_client_picture_buffers_ && !vpp_vaapi_wrapper_) { + vpp_vaapi_wrapper_ = VaapiWrapper::Create( + VaapiWrapper::kVideoProcess, VAProfileNone, + base::BindRepeating(&ReportToUMA, VAAPI_VPP_ERROR)); + if (!vpp_vaapi_wrapper_) { + VLOGF(1) << "Failed initializing VppVaapiWrapper"; + NotifyError(PLATFORM_FAILURE); + } + } + for (size_t i = 0; i < buffers.size(); ++i) { DCHECK(requested_pic_size_ == buffers[i].size()); - std::unique_ptr<VaapiPicture> picture(vaapi_picture_factory_->Create( - vaapi_wrapper_, make_context_current_cb_, bind_image_cb_, buffers[i])); + // If |decode_using_client_picture_buffers_| is false, this |picture| is + // only used as a copy destination. Therefore, the VaapiWrapper used and + // owned by |picture| is |vpp_vaapi_wrapper_|. + std::unique_ptr<VaapiPicture> picture = vaapi_picture_factory_->Create( + decode_using_client_picture_buffers_ ? vaapi_wrapper_ + : vpp_vaapi_wrapper_, + make_context_current_cb_, bind_image_cb_, buffers[i]); RETURN_AND_NOTIFY_ON_FAILURE(picture, "Failed creating a VaapiPicture", PLATFORM_FAILURE, ); @@ -670,30 +661,21 @@ surfaces_available_.Signal(); } - decode_using_client_picture_buffers_ = - ShouldDecodeOnclientPictureBuffers(profile_, !va_surface_ids.empty()); - - // 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_|, we use |va_surface_ids| for + // decode, otherwise ask |vaapi_wrapper_| to allocate them for us. if (decode_using_client_picture_buffers_) { + DCHECK(!va_surface_ids.empty()); RETURN_AND_NOTIFY_ON_FAILURE( vaapi_wrapper_->CreateContext(va_format, requested_pic_size_), "Failed creating VA Context", PLATFORM_FAILURE, ); - DCHECK_EQ(va_surface_ids.size(), buffers.size()); } else { - // If |requested_num_reference_frames_| == 0 here it's because we were too - // optimistic when calling ShouldDecodeOnclientPictureBuffers() from - // InitiateSurfaceSetChange(); correct it here. - const size_t requested_num_va_surfaces = - requested_num_reference_frames_ ? requested_num_reference_frames_ - : buffers.size(); va_surface_ids.clear(); RETURN_AND_NOTIFY_ON_FAILURE( - vaapi_wrapper_->CreateContextAndSurfaces(va_format, requested_pic_size_, - requested_num_va_surfaces, - &va_surface_ids), + vaapi_wrapper_->CreateContextAndSurfaces( + va_format, requested_pic_size_, buffers.size(), &va_surface_ids), "Failed creating VA Surfaces", PLATFORM_FAILURE, ); } + DCHECK_EQ(va_surface_ids.size(), buffers.size()); available_va_surfaces_.assign(va_surface_ids.begin(), va_surface_ids.end()); @@ -720,7 +702,6 @@ return; } - base::AutoLock auto_lock(lock_); if (!pictures_.count(picture_buffer_id)) { CloseGpuMemoryBufferHandle(gpu_memory_buffer_handle); @@ -755,25 +736,25 @@ TRACE_EVENT1("media,gpu", "VAVDA::ReusePictureBuffer", "Picture id", picture_buffer_id); + if (!pictures_.count(picture_buffer_id)) { + // It's possible that we've already posted a DismissPictureBuffer for this + // picture, but it has not yet executed when this ReusePictureBuffer + // was posted to us by the client. In that case just ignore this (we've + // already dismissed it and accounted for that). + DVLOGF(3) << "got picture id=" << picture_buffer_id + << " not in use (anymore?)."; + return; + } + { base::AutoLock auto_lock(lock_); - - if (!pictures_.count(picture_buffer_id)) { - // It's possible that we've already posted a DismissPictureBuffer for this - // picture, but it has not yet executed when this ReusePictureBuffer - // was posted to us by the client. In that case just ignore this (we've - // already dismissed it and accounted for that). - DVLOGF(3) << "got picture id=" << picture_buffer_id - << " not in use (anymore?)."; - return; - } - available_picture_buffers_.push_back(picture_buffer_id); - TRACE_COUNTER_ID2("media,gpu", "Vaapi frames at client", this, "used", - pictures_.size() - available_picture_buffers_.size(), - "available", available_picture_buffers_.size()); } + TRACE_COUNTER_ID2("media,gpu", "Vaapi frames at client", this, "used", + pictures_.size() - available_picture_buffers_.size(), + "available", available_picture_buffers_.size()); + TryOutputPicture(); } @@ -985,10 +966,10 @@ if (state_ == kResetting || state_ == kDestroying) return; } + pending_output_cbs_.push( base::BindOnce(&VaapiVideoDecodeAccelerator::OutputPicture, weak_this_, dec_surface, bitstream_id, visible_rect, color_space)); - TryOutputPicture(); } @@ -1004,10 +985,9 @@ const VASurfaceID id = available_va_surfaces_.front(); available_va_surfaces_.pop_front(); - TRACE_COUNTER_ID2( - "media,gpu", "Vaapi VASurfaceIDs", this, "used", - requested_num_reference_frames_ - available_va_surfaces_.size(), - "available", available_va_surfaces_.size()); + TRACE_COUNTER_ID2("media,gpu", "Vaapi VASurfaceIDs", this, "used", + pictures_.size() - available_va_surfaces_.size(), + "available", available_va_surfaces_.size()); return new VASurface(id, requested_pic_size_, vaapi_wrapper_->va_surface_format(), @@ -1037,17 +1017,14 @@ void VaapiVideoDecodeAccelerator::RecycleVASurfaceID( VASurfaceID va_surface_id) { DCHECK(task_runner_->BelongsToCurrentThread()); - { - base::AutoLock auto_lock(lock_); - available_va_surfaces_.push_back(va_surface_id); - if (!decode_using_client_picture_buffers_) { - TRACE_COUNTER_ID2( - "media,gpu", "Vaapi VASurfaceIDs", this, "used", - requested_num_reference_frames_ - available_va_surfaces_.size(), - "available", available_va_surfaces_.size()); - } - surfaces_available_.Signal(); + base::AutoLock auto_lock(lock_); + available_va_surfaces_.push_back(va_surface_id); + if (!decode_using_client_picture_buffers_) { + TRACE_COUNTER_ID2("media,gpu", "Vaapi VASurfaceIDs", this, "used", + pictures_.size() - available_va_surfaces_.size(), + "available", available_va_surfaces_.size()); } + surfaces_available_.Signal(); TryOutputPicture(); } @@ -1056,7 +1033,7 @@ base::trace_event::ProcessMemoryDump* pmd) { using base::trace_event::MemoryAllocatorDump; base::AutoLock auto_lock(lock_); - if (decode_using_client_picture_buffers_ || !requested_num_reference_frames_) + if (decode_using_client_picture_buffers_ || pictures_.empty()) return false; auto dump_name = base::StringPrintf("gpu/vaapi/decoder/0x%" PRIxPTR, @@ -1071,17 +1048,16 @@ const float va_surface_bytes_per_pixel = va_surface_format == VA_RT_FORMAT_YUV420 ? kNumBytesPerPixelYUV420 : kNumBytesPerPixelYUV420_10bpp; - // Report |requested_num_reference_frames_| and the associated memory size. + // Report |pictures_.size()| and the associated memory size. // The calculated size is an estimation since we don't know the internal VA // strides, texture compression, headers, etc, but is a good lower boundary. - dump->AddScalar(MemoryAllocatorDump::kNameSize, - MemoryAllocatorDump::kUnitsBytes, - static_cast<uint64_t>(requested_num_reference_frames_ * - requested_pic_size_.GetArea() * - va_surface_bytes_per_pixel)); + dump->AddScalar( + MemoryAllocatorDump::kNameSize, MemoryAllocatorDump::kUnitsBytes, + static_cast<uint64_t>(pictures_.size() * requested_pic_size_.GetArea() * + va_surface_bytes_per_pixel)); dump->AddScalar(MemoryAllocatorDump::kNameObjectCount, MemoryAllocatorDump::kUnitsObjects, - static_cast<uint64_t>(requested_num_reference_frames_)); + static_cast<uint64_t>(pictures_.size())); return true; }
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator.h b/media/gpu/vaapi/vaapi_video_decode_accelerator.h index 4906cb7f..898f266 100644 --- a/media/gpu/vaapi/vaapi_video_decode_accelerator.h +++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.h
@@ -25,7 +25,6 @@ #include "base/single_thread_task_runner.h" #include "base/synchronization/condition_variable.h" #include "base/synchronization/lock.h" -#include "base/thread_annotations.h" #include "base/threading/thread.h" #include "base/trace_event/memory_dump_provider.h" #include "media/base/bitstream_buffer.h" @@ -116,16 +115,16 @@ // |decoder_|. This method will sleep if no |input_buffers_| are available. // Returns true if a new buffer has been set up, false if an early exit has // been requested (due to initiated reset/flush/destroy). - bool GetCurrInputBuffer_Locked() EXCLUSIVE_LOCKS_REQUIRED(lock_); + bool GetCurrInputBuffer_Locked(); // Signals the client that |curr_input_buffer_| has been read and can be // returned. Will also release the mapping. - void ReturnCurrInputBuffer_Locked() EXCLUSIVE_LOCKS_REQUIRED(lock_); + void ReturnCurrInputBuffer_Locked(); // Waits for more surfaces to become available. Returns true once they do or // false if an early exit has been requested (due to an initiated // reset/flush/destroy). - bool WaitForSurfaces_Locked() EXCLUSIVE_LOCKS_REQUIRED(lock_); + bool WaitForSurfaces_Locked(); // Continue decoding given input buffers and sleep waiting for input/output // as needed. Will exit if a new set of surfaces or reset/flush/destroy @@ -178,12 +177,9 @@ // |available_va_surfaces_| void RecycleVASurfaceID(VASurfaceID va_surface_id); - // Request a new set of |num_pics| PictureBuffers to be allocated by - // |client_|. Up to |num_reference_frames| out of |num_pics_| might be needed - // by |decoder_|. - void InitiateSurfaceSetChange(size_t num_pics, - gfx::Size size, - size_t num_reference_frames); + // Initiate wait cycle for surfaces to be released before we release them + // and allocate new ones, as requested by the decoder. + void InitiateSurfaceSetChange(size_t num_pics, gfx::Size size); // Check if the surfaces have been released or post ourselves for later. void TryFinishSurfaceSetChange(); @@ -202,42 +198,42 @@ kDestroying, }; + // |lock_| protects |input_buffers_|, |curr_input_buffer_|, |state_| and + // |available_picture_buffers_|. base::Lock lock_; - State state_ GUARDED_BY(lock_); - // Only used on |task_runner_|. + State state_; Config::OutputMode output_mode_; // Queue of available InputBuffers. - base::queue<std::unique_ptr<InputBuffer>> input_buffers_ GUARDED_BY(lock_); + base::queue<std::unique_ptr<InputBuffer>> input_buffers_; // Signalled when input buffers are queued onto |input_buffers_| queue. base::ConditionVariable input_ready_; - // Current input buffer at decoder. Only used on |decoder_thread_task_runner_| + // Current input buffer at decoder. std::unique_ptr<InputBuffer> curr_input_buffer_; - // Only used on |task_runner_|. std::unique_ptr<VaapiPictureFactory> vaapi_picture_factory_; - // The following variables are constructed/initialized in Initialize() when - // the codec information is received. |vaapi_wrapper_| is thread safe. + // Constructed in Initialize() when the codec information is received. scoped_refptr<VaapiWrapper> vaapi_wrapper_; - // Only used on |decoder_thread_task_runner_|. std::unique_ptr<AcceleratedVideoDecoder> decoder_; - VideoCodecProfile profile_; + + // VaapiWrapper for VPP (Video Post Processing). This is used for copying + // from a decoded surface to a surface bound to client's PictureBuffer. + scoped_refptr<VaapiWrapper> vpp_vaapi_wrapper_; // All allocated VaapiPictures, regardless of their current state. Pictures // are allocated at AssignPictureBuffers() and are kept until dtor or // TryFinishSurfaceSetChange(). Comes after |vaapi_wrapper_| to ensure all // pictures are destroyed before this is destroyed. - base::small_map<std::map<int32_t, std::unique_ptr<VaapiPicture>>> pictures_ - GUARDED_BY(lock_); + base::small_map<std::map<int32_t, std::unique_ptr<VaapiPicture>>> pictures_; // List of PictureBuffer ids available to be sent to |client_| via // OutputPicture() (|client_| returns them via ReusePictureBuffer()). - std::list<int32_t> available_picture_buffers_ GUARDED_BY(lock_); + std::list<int32_t> available_picture_buffers_; // VASurfaceIDs no longer in use that can be passed back to |decoder_| for // reuse, once it requests them. - std::list<VASurfaceID> available_va_surfaces_ GUARDED_BY(lock_); + std::list<VASurfaceID> available_va_surfaces_; // Signalled when output surfaces are queued into |available_va_surfaces_|. base::ConditionVariable surfaces_available_; @@ -249,13 +245,15 @@ // If we don't have any available |pictures_| at the time when the decoder // requests output, we'll store the request in this queue for later and run it // once the client gives us more textures via ReusePictureBuffer(). - // Only used on |task_runner_|. 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. Only used on |task_runner_|. + // decode onto, which skips one copy. bool decode_using_client_picture_buffers_; + // ChildThread's 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 // this class, any task running on the decoder thread is guaranteed that this @@ -264,37 +262,33 @@ // decoder thread to the ChildThread should use |weak_this_|. base::WeakPtr<VaapiVideoDecodeAccelerator> weak_this_; - // Callback used when creating VASurface objects. Only used on |task_runner_|. + // Callback used when creating VASurface objects. VASurface::ReleaseCB va_surface_release_cb_; - // To expose client callbacks from VideoDecodeAccelerator. Used only on - // |task_runner_|. + // To expose client callbacks from VideoDecodeAccelerator. + // NOTE: all calls to these objects *MUST* be executed on task_runner_. std::unique_ptr<base::WeakPtrFactory<Client>> client_ptr_factory_; base::WeakPtr<Client> client_; - // ChildThread's task runner. - const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - base::Thread decoder_thread_; // Use this to post tasks to |decoder_thread_| instead of // |decoder_thread_.task_runner()| because the latter will be NULL once // |decoder_thread_.Stop()| returns. scoped_refptr<base::SingleThreadTaskRunner> decoder_thread_task_runner_; - // Whether we are waiting for any |pending_output_cbs_| to be run before - // NotifyingFlushDone. Only used on |task_runner_|. + // Whether we are waiting for any pending_output_cbs_ to be run before + // NotifyingFlushDone. bool finish_flush_pending_; // Decoder requested a new surface set and we are waiting for all the surfaces - // to be returned before we can free them. Only used on |task_runner_|. + // to be returned before we can free them. bool awaiting_va_surfaces_recycle_; - // Last requested number/resolution of output PictureBuffers. + // Last requested number/resolution of output picture buffers and their + // format. size_t requested_num_pics_; gfx::Size requested_pic_size_; - // Max number of reference frames needed by |decoder_|. - size_t requested_num_reference_frames_; - size_t previously_requested_num_reference_frames_; + VideoCodecProfile profile_; // Callback to make GL context current. MakeGLContextCurrentCallback make_context_current_cb_;
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc index b9819cd..3041c10e 100644 --- a/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc +++ b/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc
@@ -37,7 +37,7 @@ constexpr int32_t kBitstreamId = 123; constexpr size_t kInputSize = 256; -constexpr size_t kNumPictures = 4; +constexpr size_t kNumPictures = 2; const gfx::Size kPictureSize(64, 48); constexpr size_t kNewNumPictures = 3; @@ -58,7 +58,6 @@ MOCK_METHOD0(Decode, DecodeResult()); MOCK_CONST_METHOD0(GetPicSize, gfx::Size()); MOCK_CONST_METHOD0(GetRequiredNumOfPictures, size_t()); - MOCK_CONST_METHOD0(GetNumReferenceFrames, size_t()); }; class MockVaapiWrapper : public VaapiWrapper { @@ -141,6 +140,7 @@ mock_decoder_(new MockAcceleratedVideoDecoder), mock_vaapi_picture_factory_(new MockVaapiPictureFactory()), mock_vaapi_wrapper_(new MockVaapiWrapper()), + mock_vpp_vaapi_wrapper_(new MockVaapiWrapper()), weak_ptr_factory_(this) { decoder_thread_.Start(); @@ -152,6 +152,7 @@ vda_.decoder_.reset(mock_decoder_); vda_.client_ = weak_ptr_factory_.GetWeakPtr(); vda_.vaapi_wrapper_ = mock_vaapi_wrapper_; + vda_.vpp_vaapi_wrapper_ = mock_vpp_vaapi_wrapper_; vda_.vaapi_picture_factory_.reset(mock_vaapi_picture_factory_); vda_.state_ = VaapiVideoDecodeAccelerator::kIdle; @@ -164,7 +165,6 @@ } void SetVdaStateToUnitialized() { - base::AutoLock auto_lock(vda_.lock_); vda_.state_ = VaapiVideoDecodeAccelerator::kUninitialized; } @@ -207,9 +207,6 @@ EXPECT_CALL(*mock_decoder_, GetRequiredNumOfPictures()) .WillOnce(Return(num_pictures)); EXPECT_CALL(*mock_decoder_, GetPicSize()).WillOnce(Return(picture_size)); - const size_t kNumReferenceFrames = num_pictures / 2; - EXPECT_CALL(*mock_decoder_, GetNumReferenceFrames()) - .WillOnce(Return(kNumReferenceFrames)); EXPECT_CALL(*mock_vaapi_wrapper_, DestroyContextAndSurfaces()); if (expect_dismiss_picture_buffers) { @@ -217,8 +214,8 @@ .Times(num_picture_buffers_to_dismiss); } - EXPECT_CALL(*this, ProvidePictureBuffers(num_pictures - kNumReferenceFrames, - _, 1, picture_size, _)) + EXPECT_CALL(*this, + ProvidePictureBuffers(num_pictures, _, 1, picture_size, _)) .WillOnce(RunClosure(quit_closure)); base::SharedMemoryHandle handle; @@ -242,18 +239,20 @@ base::RunLoop run_loop; base::Closure quit_closure = run_loop.QuitClosure(); - const size_t kNumReferenceFrames = num_pictures / 2; + // TODO(crbug.com/): We assume that |decode_using_client_picture_buffers_| + // is false, we should also support a pattern when + // |decode_using_client_picture_buffers_|. + EXPECT_CALL(*mock_vaapi_wrapper_, + CreateContextAndSurfaces(_, picture_size, num_pictures, _)) + .WillOnce( + DoAll(WithArg<3>(Invoke( + [num_pictures](std::vector<VASurfaceID>* va_surface_ids) { + va_surface_ids->resize(num_pictures); + })), + Return(true))); EXPECT_CALL( - *mock_vaapi_wrapper_, - CreateContextAndSurfaces(_, picture_size, kNumReferenceFrames, _)) - .WillOnce(DoAll( - WithArg<3>(Invoke([kNumReferenceFrames]( - std::vector<VASurfaceID>* va_surface_ids) { - va_surface_ids->resize(kNumReferenceFrames); - })), - Return(true))); - EXPECT_CALL(*mock_vaapi_picture_factory_, - MockCreateVaapiPicture(mock_vaapi_wrapper_.get(), picture_size)) + *mock_vaapi_picture_factory_, + MockCreateVaapiPicture(mock_vpp_vaapi_wrapper_.get(), picture_size)) .Times(num_pictures); ::testing::InSequence s; @@ -321,6 +320,7 @@ MockVaapiPictureFactory* mock_vaapi_picture_factory_; scoped_refptr<MockVaapiWrapper> mock_vaapi_wrapper_; + scoped_refptr<MockVaapiWrapper> mock_vpp_vaapi_wrapper_; std::unique_ptr<base::SharedMemory> in_shm_;
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc index 284736f..def3b06 100644 --- a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc +++ b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
@@ -446,7 +446,7 @@ uint8_t* target_data = static_cast<uint8_t*>(buffer->shm->memory()); size_t data_size = 0; - if (!vaapi_wrapper_->DownloadAndDestroyCodedBuffer( + if (!vaapi_wrapper_->DownloadAndDestroyVABuffer( encode_job->coded_buffer_id(), encode_job->input_surface()->id(), target_data, buffer->shm->size(), &data_size)) { NOTIFY_ERROR(kPlatformFailureError, "Failed downloading coded buffer"); @@ -497,8 +497,8 @@ } VABufferID coded_buffer_id; - if (!vaapi_wrapper_->CreateCodedBuffer(output_buffer_byte_size_, - &coded_buffer_id)) { + if (!vaapi_wrapper_->CreateVABuffer(output_buffer_byte_size_, + &coded_buffer_id)) { NOTIFY_ERROR(kPlatformFailureError, "Failed creating coded buffer"); return nullptr; }
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc index c1cde04f..6daab8b 100644 --- a/media/gpu/vaapi/vaapi_wrapper.cc +++ b/media/gpu/vaapi/vaapi_wrapper.cc
@@ -371,6 +371,10 @@ VAProfile profile) { std::vector<VAConfigAttrib> required_attribs; + // No attribute for kVideoProcess. + if (mode == VaapiWrapper::kVideoProcess) + return required_attribs; + // VAConfigAttribRTFormat is common to both encode and decode |mode|s. if (profile == VAProfileVP9Profile2 || profile == VAProfileVP9Profile3) { required_attribs.push_back( @@ -406,6 +410,8 @@ return VAEntrypointEncPicture; else return VAEntrypointEncSlice; + case VaapiWrapper::kVideoProcess: + return VAEntrypointVideoProc; case VaapiWrapper::kCodecModeMax: NOTREACHED(); return VAEntrypointVLD; @@ -527,6 +533,9 @@ std::vector<VASupportedProfiles::ProfileInfo> VASupportedProfiles::GetSupportedProfileInfosForCodecModeInternal( VaapiWrapper::CodecMode mode) const { + if (mode == VaapiWrapper::kVideoProcess) + return {ProfileInfo{VAProfileNone, gfx::Size()}}; + std::vector<ProfileInfo> supported_profile_infos; std::vector<VAProfile> va_profiles; if (!GetSupportedVAProfiles(&va_profiles)) @@ -1240,23 +1249,23 @@ return ret == 0; } -bool VaapiWrapper::CreateCodedBuffer(size_t size, VABufferID* buffer_id) { +bool VaapiWrapper::CreateVABuffer(size_t size, VABufferID* buffer_id) { base::AutoLock auto_lock(*va_lock_); VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_, VAEncCodedBufferType, size, 1, NULL, buffer_id); VA_SUCCESS_OR_RETURN(va_res, "Failed to create a coded buffer", false); - const auto is_new_entry = coded_buffers_.insert(*buffer_id).second; + const auto is_new_entry = va_buffers_.insert(*buffer_id).second; DCHECK(is_new_entry); return true; } -bool VaapiWrapper::DownloadFromCodedBuffer(VABufferID buffer_id, - VASurfaceID sync_surface_id, - uint8_t* target_ptr, - size_t target_size, - size_t* coded_data_size) { +bool VaapiWrapper::DownloadFromVABuffer(VABufferID buffer_id, + VASurfaceID sync_surface_id, + uint8_t* target_ptr, + size_t target_size, + size_t* coded_data_size) { DCHECK(target_ptr); base::AutoLock auto_lock(*va_lock_); @@ -1296,48 +1305,42 @@ return buffer_segment == nullptr; } -bool VaapiWrapper::DownloadAndDestroyCodedBuffer(VABufferID buffer_id, - VASurfaceID sync_surface_id, - uint8_t* target_ptr, - size_t target_size, - size_t* coded_data_size) { - bool result = DownloadFromCodedBuffer(buffer_id, sync_surface_id, target_ptr, - target_size, coded_data_size); +bool VaapiWrapper::DownloadAndDestroyVABuffer(VABufferID buffer_id, + VASurfaceID sync_surface_id, + uint8_t* target_ptr, + size_t target_size, + size_t* coded_data_size) { + bool result = DownloadFromVABuffer(buffer_id, sync_surface_id, target_ptr, + target_size, coded_data_size); base::AutoLock auto_lock(*va_lock_); VAStatus va_res = vaDestroyBuffer(va_display_, buffer_id); VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); - const auto was_found = coded_buffers_.erase(buffer_id); + const auto was_found = va_buffers_.erase(buffer_id); DCHECK(was_found); return result; } -void VaapiWrapper::DestroyCodedBuffers() { +void VaapiWrapper::DestroyVABuffers() { base::AutoLock auto_lock(*va_lock_); - for (std::set<VABufferID>::const_iterator iter = coded_buffers_.begin(); - iter != coded_buffers_.end(); ++iter) { - VAStatus va_res = vaDestroyBuffer(va_display_, *iter); + for (auto it = va_buffers_.begin(); it != va_buffers_.end(); ++it) { + VAStatus va_res = vaDestroyBuffer(va_display_, *it); VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); } - coded_buffers_.clear(); + va_buffers_.clear(); } bool VaapiWrapper::BlitSurface( const scoped_refptr<VASurface>& va_surface_src, const scoped_refptr<VASurface>& va_surface_dest) { base::AutoLock auto_lock(*va_lock_); - - // Initialize the post processing engine if not already done. - if (va_vpp_buffer_id_ == VA_INVALID_ID) { - if (!InitializeVpp_Locked()) - return false; - } - + DCHECK_EQ(va_buffers_.size(), 1u); + VABufferID buffer_id = *va_buffers_.begin(); { - ScopedVABufferMapping mapping(va_lock_, va_display_, va_vpp_buffer_id_); + ScopedVABufferMapping mapping(va_lock_, va_display_, buffer_id); if (!mapping.IsValid()) return false; auto* pipeline_param = @@ -1368,14 +1371,14 @@ } VA_SUCCESS_OR_RETURN( - vaBeginPicture(va_display_, va_vpp_context_id_, va_surface_dest->id()), + vaBeginPicture(va_display_, va_context_id_, va_surface_dest->id()), "Couldn't begin picture", false); VA_SUCCESS_OR_RETURN( - vaRenderPicture(va_display_, va_vpp_context_id_, &va_vpp_buffer_id_, 1), + vaRenderPicture(va_display_, va_context_id_, &buffer_id, 1), "Couldn't render picture", false); - VA_SUCCESS_OR_RETURN(vaEndPicture(va_display_, va_vpp_context_id_), + VA_SUCCESS_OR_RETURN(vaEndPicture(va_display_, va_context_id_), "Couldn't end picture", false); return true; @@ -1423,31 +1426,49 @@ va_surface_format_(0), va_display_(NULL), va_config_id_(VA_INVALID_ID), - va_context_id_(VA_INVALID_ID), - va_vpp_config_id_(VA_INVALID_ID), - va_vpp_context_id_(VA_INVALID_ID), - va_vpp_buffer_id_(VA_INVALID_ID) {} + va_context_id_(VA_INVALID_ID) {} VaapiWrapper::~VaapiWrapper() { DestroyPendingBuffers(); - DestroyCodedBuffers(); + DestroyVABuffers(); DestroyContextAndSurfaces(); - DeinitializeVpp(); Deinitialize(); } bool VaapiWrapper::Initialize(CodecMode mode, VAProfile va_profile) { - TryToSetVADisplayAttributeToLocalGPU(); + if (mode != kVideoProcess) + TryToSetVADisplayAttributeToLocalGPU(); VAEntrypoint entrypoint = GetVaEntryPoint(mode, va_profile); std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode, va_profile); + base::AutoLock auto_lock(*va_lock_); + VAStatus va_res = - vaCreateConfig(va_display_, va_profile, entrypoint, &required_attribs[0], + vaCreateConfig(va_display_, va_profile, entrypoint, + required_attribs.empty() ? nullptr : &required_attribs[0], required_attribs.size(), &va_config_id_); VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false); + if (mode != kVideoProcess) + return true; + + // Creates context and buffer here in the case of kVideoProcess. + constexpr size_t kIrrelevantWidth = 0; + constexpr size_t kIrrelevantHeight = 0; + va_res = vaCreateContext(va_display_, va_config_id_, kIrrelevantWidth, + kIrrelevantHeight, 0, NULL, 0, &va_context_id_); + VA_SUCCESS_OR_RETURN(va_res, "Couldn't create context", false); + + VABufferID buffer_id; + va_res = vaCreateBuffer( + va_display_, va_context_id_, VAProcPipelineParameterBufferType, + sizeof(VAProcPipelineParameterBuffer), 1, NULL, &buffer_id); + VA_SUCCESS_OR_RETURN(va_res, "Couldn't create buffer", false); + DCHECK_NE(buffer_id, VA_INVALID_ID); + va_buffers_.emplace(buffer_id); + return true; } @@ -1488,46 +1509,6 @@ VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces on surface failed"); } -bool VaapiWrapper::InitializeVpp_Locked() { - va_lock_->AssertAcquired(); - - VA_SUCCESS_OR_RETURN( - vaCreateConfig(va_display_, VAProfileNone, VAEntrypointVideoProc, NULL, 0, - &va_vpp_config_id_), - "Couldn't create config", false); - - // The size of the picture for the context is irrelevant in the case - // of the VPP, just passing 1x1. - VA_SUCCESS_OR_RETURN(vaCreateContext(va_display_, va_vpp_config_id_, 1, 1, 0, - NULL, 0, &va_vpp_context_id_), - "Couldn't create context", false); - - VA_SUCCESS_OR_RETURN(vaCreateBuffer(va_display_, va_vpp_context_id_, - VAProcPipelineParameterBufferType, - sizeof(VAProcPipelineParameterBuffer), 1, - NULL, &va_vpp_buffer_id_), - "Couldn't create buffer", false); - - return true; -} - -void VaapiWrapper::DeinitializeVpp() { - base::AutoLock auto_lock(*va_lock_); - - if (va_vpp_buffer_id_ != VA_INVALID_ID) { - vaDestroyBuffer(va_display_, va_vpp_buffer_id_); - va_vpp_buffer_id_ = VA_INVALID_ID; - } - if (va_vpp_context_id_ != VA_INVALID_ID) { - vaDestroyContext(va_display_, va_vpp_context_id_); - va_vpp_context_id_ = VA_INVALID_ID; - } - if (va_vpp_config_id_ != VA_INVALID_ID) { - vaDestroyConfig(va_display_, va_vpp_config_id_); - va_vpp_config_id_ = VA_INVALID_ID; - } -} - bool VaapiWrapper::Execute(VASurfaceID va_surface_id) { TRACE_EVENT0("media,gpu", "VaapiWrapper::Execute"); base::AutoLock auto_lock(*va_lock_);
diff --git a/media/gpu/vaapi/vaapi_wrapper.h b/media/gpu/vaapi/vaapi_wrapper.h index 01dd570..7b5a239 100644 --- a/media/gpu/vaapi/vaapi_wrapper.h +++ b/media/gpu/vaapi/vaapi_wrapper.h
@@ -60,6 +60,7 @@ enum CodecMode { kDecode, kEncode, + kVideoProcess, kCodecModeMax, }; @@ -179,7 +180,7 @@ VASurfaceID va_surface_id); // Create a buffer of |size| bytes to be used as encode output. - bool CreateCodedBuffer(size_t size, VABufferID* buffer_id); + bool CreateVABuffer(size_t size, VABufferID* buffer_id); // Download the contents of the buffer with given |buffer_id| into a buffer of // size |target_size|, pointed to by |target_ptr|. The number of bytes @@ -187,22 +188,22 @@ // be used as a sync point, i.e. it will have to become idle before starting // the download. |sync_surface_id| should be the source surface passed // to the encode job. - bool DownloadFromCodedBuffer(VABufferID buffer_id, - VASurfaceID sync_surface_id, - uint8_t* target_ptr, - size_t target_size, - size_t* coded_data_size); + bool DownloadFromVABuffer(VABufferID buffer_id, + VASurfaceID sync_surface_id, + uint8_t* target_ptr, + size_t target_size, + size_t* coded_data_size); - // See DownloadFromCodedBuffer() for details. After downloading, it deletes + // See DownloadFromVABuffer() for details. After downloading, it deletes // the VA buffer with |buffer_id|. - bool DownloadAndDestroyCodedBuffer(VABufferID buffer_id, - VASurfaceID sync_surface_id, - uint8_t* target_ptr, - size_t target_size, - size_t* coded_data_size); + bool DownloadAndDestroyVABuffer(VABufferID buffer_id, + VASurfaceID sync_surface_id, + uint8_t* target_ptr, + size_t target_size, + size_t* coded_data_size); - // Destroy all previously-allocated (and not yet destroyed) coded buffers. - void DestroyCodedBuffers(); + // Destroy all previously-allocated (and not yet destroyed) buffers. + void DestroyVABuffers(); // Blits a VASurface |va_surface_src| into another VASurface // |va_surface_dest| applying pixel format conversion and scaling @@ -231,13 +232,6 @@ // Destroys a |va_surface_id|. void DestroySurface(VASurfaceID va_surface_id); - // Initialize the video post processing context with the |size| of - // the input pictures to be processed. - bool InitializeVpp_Locked() EXCLUSIVE_LOCKS_REQUIRED(va_lock_); - - // Deinitialize the video post processing context. - void DeinitializeVpp(); - // Execute pending job in hardware and destroy pending buffers. Return false // if vaapi driver refuses to accept parameter or slice buffers submitted // by client, or if execution fails in hardware. @@ -268,20 +262,13 @@ std::vector<VABufferID> pending_slice_bufs_; std::vector<VABufferID> pending_va_bufs_; - // Bitstream buffers for encode. - std::set<VABufferID> coded_buffers_; + // Buffers for kEncode or kVideoProcess. + std::set<VABufferID> va_buffers_; // Called to report codec errors to UMA. Errors to clients are reported via // return values from public methods. base::Closure report_error_to_uma_cb_; - // VPP (Video Post Processing) context, this is used to convert - // pictures used by the decoder to RGBA pictures usable by GL or the - // display hardware. - VAConfigID va_vpp_config_id_; - VAContextID va_vpp_context_id_; - VABufferID va_vpp_buffer_id_; - DISALLOW_COPY_AND_ASSIGN(VaapiWrapper); };
diff --git a/media/gpu/vp8_decoder.cc b/media/gpu/vp8_decoder.cc index c86f71825..33a181d 100644 --- a/media/gpu/vp8_decoder.cc +++ b/media/gpu/vp8_decoder.cc
@@ -7,10 +7,6 @@ namespace media { -namespace { -constexpr size_t kVP8NumFramesActive = 4; -}; - VP8Decoder::VP8Accelerator::VP8Accelerator() {} VP8Decoder::VP8Accelerator::~VP8Accelerator() {} @@ -169,14 +165,9 @@ } size_t VP8Decoder::GetRequiredNumOfPictures() const { - constexpr size_t kPicsInPipeline = limits::kMaxVideoFrames + 1; + const size_t kVP8NumFramesActive = 4; + const size_t kPicsInPipeline = limits::kMaxVideoFrames + 2; return kVP8NumFramesActive + kPicsInPipeline; } -size_t VP8Decoder::GetNumReferenceFrames() const { - // Maximum number of reference frames needed plus one for the one being - // currently egressed. - return kVP8NumFramesActive + 1; -} - } // namespace media
diff --git a/media/gpu/vp8_decoder.h b/media/gpu/vp8_decoder.h index 8ed398b89..f08a8126 100644 --- a/media/gpu/vp8_decoder.h +++ b/media/gpu/vp8_decoder.h
@@ -72,7 +72,6 @@ DecodeResult Decode() override WARN_UNUSED_RESULT; gfx::Size GetPicSize() const override; size_t GetRequiredNumOfPictures() const override; - size_t GetNumReferenceFrames() const override; private: bool DecodeAndOutputCurrentFrame(scoped_refptr<VP8Picture> pic);
diff --git a/media/gpu/vp9_decoder.cc b/media/gpu/vp9_decoder.cc index a8d2f2a..a16c6a9 100644 --- a/media/gpu/vp9_decoder.cc +++ b/media/gpu/vp9_decoder.cc
@@ -261,14 +261,9 @@ } size_t VP9Decoder::GetRequiredNumOfPictures() const { - constexpr size_t kPicsInPipeline = limits::kMaxVideoFrames + 1; - return kPicsInPipeline + GetNumReferenceFrames(); -} - -size_t VP9Decoder::GetNumReferenceFrames() const { - // Maximum number of reference frames needed plus one for the one being - // currently egressed. - return kVp9NumRefFrames + 1; + // kMaxVideoFrames to keep higher level media pipeline populated, +2 for the + // pictures being parsed and decoded currently. + return limits::kMaxVideoFrames + kVp9NumRefFrames + 2; } } // namespace media
diff --git a/media/gpu/vp9_decoder.h b/media/gpu/vp9_decoder.h index b4422f0..3bf20061 100644 --- a/media/gpu/vp9_decoder.h +++ b/media/gpu/vp9_decoder.h
@@ -106,7 +106,6 @@ DecodeResult Decode() override WARN_UNUSED_RESULT; gfx::Size GetPicSize() const override; size_t GetRequiredNumOfPictures() const override; - size_t GetNumReferenceFrames() const override; private: // Update ref_frames_ based on the information in current frame header.
diff --git a/media/gpu/windows/d3d11_h264_accelerator.cc b/media/gpu/windows/d3d11_h264_accelerator.cc index ecc7a52..edbfb90 100644 --- a/media/gpu/windows/d3d11_h264_accelerator.cc +++ b/media/gpu/windows/d3d11_h264_accelerator.cc
@@ -73,7 +73,12 @@ cdm_proxy_context_(cdm_proxy_context), video_decoder_(video_decoder), video_device_(video_device), - video_context_(std::move(video_context)) {} + video_context_(std::move(video_context)) { + DCHECK(client); + DCHECK(media_log_); + // |cdm_proxy_context_| is non-null for encrypted content but can be null for + // clear content. +} D3D11H264Accelerator::~D3D11H264Accelerator() {} @@ -100,6 +105,7 @@ // D3D11_VIDEO_DECODER_BEGIN_FRAME_CRYPTO_SESSION is a pointer (to a GUID). base::Optional<CdmProxyContext::D3D11DecryptContext> decrypt_context; if (is_encrypted) { + DCHECK(cdm_proxy_context_) << "No CdmProxyContext but picture is encrypted"; decrypt_context = cdm_proxy_context_->GetD3D11DecryptContext( CdmProxy::KeyType::kDecryptAndDecode, pic->decrypt_config()->key_id()); if (!decrypt_context) { @@ -559,10 +565,8 @@ hr_string = ": " + logging::SystemErrorCodeToString(hr); DLOG(ERROR) << reason << hr_string; - if (media_log_) { - media_log_->AddEvent(media_log_->CreateStringEvent( - MediaLogEvent::MEDIA_ERROR_LOG_ENTRY, "error", hr_string + reason)); - } + media_log_->AddEvent(media_log_->CreateStringEvent( + MediaLogEvent::MEDIA_ERROR_LOG_ENTRY, "error", hr_string + reason)); } } // namespace media
diff --git a/media/gpu/windows/d3d11_video_decoder.cc b/media/gpu/windows/d3d11_video_decoder.cc index 3fb97d5..54803b6 100644 --- a/media/gpu/windows/d3d11_video_decoder.cc +++ b/media/gpu/windows/d3d11_video_decoder.cc
@@ -125,6 +125,7 @@ get_helper_cb_(std::move(get_helper_cb)), weak_factory_(this) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(media_log_); impl_weak_ = impl_->GetWeakPtr(); } @@ -215,6 +216,8 @@ const OutputCB& output_cb, const WaitingCB& waiting_cb) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(output_cb); + DCHECK(waiting_cb); if (!IsPotentiallySupported(config)) { DVLOG(3) << "D3D11 video decoder not supported for the config."; @@ -222,9 +225,10 @@ return; } + config_ = config; init_cb_ = init_cb; output_cb_ = output_cb; - config_ = config; + waiting_cb_ = waiting_cb; D3D11VideoDecoderImpl::InitCB cb = base::BindOnce( &D3D11VideoDecoder::OnGpuInitComplete, weak_factory_.GetWeakPtr()); @@ -471,6 +475,7 @@ CreatePictureBuffers(); } else if (result == media::AcceleratedVideoDecoder::kTryAgain) { state_ = State::kWaitingForNewKey; + waiting_cb_.Run(WaitingReason::kNoDecryptionKey); // Note that another DoDecode() task would be posted in NotifyNewKey(). return; } else { @@ -652,10 +657,8 @@ void D3D11VideoDecoder::NotifyError(const char* reason) { state_ = State::kError; DLOG(ERROR) << reason; - if (media_log_) { - media_log_->AddEvent(media_log_->CreateStringEvent( - MediaLogEvent::MEDIA_ERROR_LOG_ENTRY, "error", reason)); - } + media_log_->AddEvent(media_log_->CreateStringEvent( + MediaLogEvent::MEDIA_ERROR_LOG_ENTRY, "error", reason)); if (init_cb_) std::move(init_cb_).Run(false); @@ -705,10 +708,8 @@ } DVLOG(2) << reason; - if (media_log_) { - media_log_->AddEvent(media_log_->CreateStringEvent( - MediaLogEvent::MEDIA_INFO_LOG_ENTRY, "info", reason)); - } + media_log_->AddEvent(media_log_->CreateStringEvent( + MediaLogEvent::MEDIA_INFO_LOG_ENTRY, "info", reason)); } bool D3D11VideoDecoder::IsPotentiallySupported(
diff --git a/media/gpu/windows/d3d11_video_decoder.h b/media/gpu/windows/d3d11_video_decoder.h index 3336a656c..2d71473 100644 --- a/media/gpu/windows/d3d11_video_decoder.h +++ b/media/gpu/windows/d3d11_video_decoder.h
@@ -190,9 +190,10 @@ gpu::GpuDriverBugWorkarounds gpu_workarounds_; // During init, these will be set. + VideoDecoderConfig config_; InitCB init_cb_; OutputCB output_cb_; - VideoDecoderConfig config_; + WaitingCB waiting_cb_; D3D11CreateDeviceCB create_device_func_;
diff --git a/media/gpu/windows/d3d11_video_decoder_unittest.cc b/media/gpu/windows/d3d11_video_decoder_unittest.cc index 338bedf5..ae960fd8 100644 --- a/media/gpu/windows/d3d11_video_decoder_unittest.cc +++ b/media/gpu/windows/d3d11_video_decoder_unittest.cc
@@ -18,6 +18,7 @@ #include "media/base/decoder_buffer.h" #include "media/base/media_log.h" #include "media/base/media_switches.h" +#include "media/base/media_util.h" #include "media/base/test_helpers.h" #include "media/gpu/windows/d3d11_mocks.h" #include "media/gpu/windows/d3d11_video_decoder_impl.h" @@ -72,8 +73,8 @@ // deleter works. The dtor is protected. decoder_ = base::WrapUnique<VideoDecoder>( d3d11_decoder_raw_ = new D3D11VideoDecoder( - gpu_task_runner_, nullptr /* MediaLog */, gpu_preferences_, - gpu_workarounds_, std::move(impl), + gpu_task_runner_, std::make_unique<NullMediaLog>(), + gpu_preferences_, gpu_workarounds_, std::move(impl), base::RepeatingCallback<scoped_refptr<CommandBufferHelper>()>())); d3d11_decoder_raw_->SetCreateDeviceCallbackForTesting( base::BindRepeating(&D3D11CreateDeviceMock::Create, @@ -104,7 +105,7 @@ decoder_->Initialize(config, low_delay, cdm_context, base::BindRepeating(&D3D11VideoDecoderTest::MockInitCB, base::Unretained(this)), - VideoDecoder::OutputCB(), base::NullCallback()); + base::DoNothing(), base::DoNothing()); base::RunLoop().RunUntilIdle(); }
diff --git a/media/gpu/windows/d3d11_vp9_accelerator.cc b/media/gpu/windows/d3d11_vp9_accelerator.cc index be087ab..c3dd89f 100644 --- a/media/gpu/windows/d3d11_vp9_accelerator.cc +++ b/media/gpu/windows/d3d11_vp9_accelerator.cc
@@ -47,7 +47,12 @@ status_feedback_(0), video_decoder_(std::move(video_decoder)), video_device_(std::move(video_device)), - video_context_(std::move(video_context)) {} + video_context_(std::move(video_context)) { + DCHECK(client); + DCHECK(media_log_); + // |cdm_proxy_context_| is non-null for encrypted content but can be null for + // clear content. +} D3D11VP9Accelerator::~D3D11VP9Accelerator() {} @@ -81,6 +86,7 @@ base::Optional<CdmProxyContext::D3D11DecryptContext> decrypt_context; std::unique_ptr<D3D11_VIDEO_DECODER_BEGIN_FRAME_CRYPTO_SESSION> content_key; if (const DecryptConfig* config = pic->decrypt_config()) { + DCHECK(cdm_proxy_context_) << "No CdmProxyContext but picture is encrypted"; decrypt_context = cdm_proxy_context_->GetD3D11DecryptContext( CdmProxy::KeyType::kDecryptAndDecode, config->key_id()); if (!decrypt_context) {
diff --git a/media/gpu/windows/dxva_video_decode_accelerator_win.cc b/media/gpu/windows/dxva_video_decode_accelerator_win.cc index e728def48..e56a533 100644 --- a/media/gpu/windows/dxva_video_decode_accelerator_win.cc +++ b/media/gpu/windows/dxva_video_decode_accelerator_win.cc
@@ -270,27 +270,27 @@ bool IsResolutionSupportedForDevice(const gfx::Size& resolution_to_test, const GUID& decoder_guid, ID3D11VideoDevice* video_device) { - D3D11_VIDEO_DECODER_DESC desc = {}; - desc.Guid = decoder_guid; - desc.SampleWidth = resolution_to_test.width(); - desc.SampleHeight = resolution_to_test.height(); - desc.OutputFormat = DXGI_FORMAT_NV12; - UINT config_count = 0; - HRESULT hr = video_device->GetVideoDecoderConfigCount(&desc, &config_count); - if (FAILED(hr) || config_count == 0) - return false; + D3D11_VIDEO_DECODER_DESC desc = { + decoder_guid, // Guid + resolution_to_test.width(), // SampleWidth + resolution_to_test.height(), // SampleHeight + DXGI_FORMAT_NV12 // OutputFormat + }; - D3D11_VIDEO_DECODER_CONFIG config = {}; - hr = video_device->GetVideoDecoderConfig(&desc, 0, &config); - UMA_HISTOGRAM_BOOLEAN("Media.DXVAVDA.GetDecoderConfigStatus", SUCCEEDED(hr)); - if (FAILED(hr)) - return false; - - Microsoft::WRL::ComPtr<ID3D11VideoDecoder> video_decoder; - hr = video_device->CreateVideoDecoder(&desc, &config, - video_decoder.GetAddressOf()); - UMA_HISTOGRAM_BOOLEAN("Media.DXVAVDA.CreateDecoderStatus", !!video_decoder); - return !!video_decoder; + // We've chosen the least expensive test for identifying if a given resolution + // is supported. Actually creating the VideoDecoder instance only fails ~0.4% + // of the time and the outcome is that we will offer support and then + // immediately fall back to software; e.g., playback still works. Since these + // calls can take hundreds of milliseconds to complete and are often executed + // during startup, this seems a reasonably trade off. + // + // See the deprecated histograms Media.DXVAVDA.GetDecoderConfigStatus which + // succeeds 100% of the time and Media.DXVAVDA.CreateDecoderStatus which + // only succeeds 99.6% of the time (in a 28 day aggregation). + UINT config_count; + return SUCCEEDED( + video_device->GetVideoDecoderConfigCount(&desc, &config_count)) && + config_count > 0; } // Returns a tuple of (LandscapeMax, PortraitMax). If landscape maximum can not @@ -2977,10 +2977,8 @@ PictureBufferMechanism::DELAYED_COPY_TO_NV12) { // If we're copying NV12 textures, make sure we set the same // color space on input and output. - D3D11_VIDEO_PROCESSOR_COLOR_SPACE d3d11_color_space = {0}; - d3d11_color_space.RGB_Range = 1; - d3d11_color_space.Nominal_Range = D3D11_VIDEO_PROCESSOR_NOMINAL_RANGE_0_255; - + const auto d3d11_color_space = + gfx::ColorSpaceWin::GetD3D11ColorSpace(color_space); video_context_->VideoProcessorSetOutputColorSpace(d3d11_processor_.Get(), &d3d11_color_space);
diff --git a/media/mojo/clients/mojo_audio_decoder.cc b/media/mojo/clients/mojo_audio_decoder.cc index 504f6f0a4..c10d8bcd 100644 --- a/media/mojo/clients/mojo_audio_decoder.cc +++ b/media/mojo/clients/mojo_audio_decoder.cc
@@ -46,7 +46,7 @@ CdmContext* cdm_context, const InitCB& init_cb, const OutputCB& output_cb, - const WaitingCB& /* waiting_cb */) { + const WaitingCB& waiting_cb) { DVLOG(1) << __func__; DCHECK(task_runner_->BelongsToCurrentThread()); @@ -73,6 +73,7 @@ init_cb_ = init_cb; output_cb_ = output_cb; + waiting_cb_ = waiting_cb; // Using base::Unretained(this) is safe because |this| owns |remote_decoder_|, // and the callback won't be dispatched if |remote_decoder_| is destroyed. @@ -160,6 +161,13 @@ output_cb_.Run(buffer.To<scoped_refptr<AudioBuffer>>()); } +void MojoAudioDecoder::OnWaiting(WaitingReason reason) { + DVLOG(1) << __func__; + DCHECK(task_runner_->BelongsToCurrentThread()); + + waiting_cb_.Run(reason); +} + void MojoAudioDecoder::OnConnectionError() { DVLOG(1) << __func__; DCHECK(task_runner_->BelongsToCurrentThread());
diff --git a/media/mojo/clients/mojo_audio_decoder.h b/media/mojo/clients/mojo_audio_decoder.h index 54a591cb..2c77d69 100644 --- a/media/mojo/clients/mojo_audio_decoder.h +++ b/media/mojo/clients/mojo_audio_decoder.h
@@ -45,6 +45,7 @@ // AudioDecoderClient implementation. void OnBufferDecoded(mojom::AudioBufferPtr buffer) final; + void OnWaiting(WaitingReason reason) final; void set_writer_capacity_for_testing(uint32_t capacity) { writer_capacity_ = capacity; @@ -82,11 +83,11 @@ // Binding for AudioDecoderClient, bound to the |task_runner_|. mojo::AssociatedBinding<AudioDecoderClient> client_binding_; - // We call the following callbacks to pass the information to the pipeline. - // |output_cb_| is permanent while other three are called only once, - // |decode_cb_| and |reset_cb_| are replaced by every by Decode() and Reset(). InitCB init_cb_; OutputCB output_cb_; + WaitingCB waiting_cb_; + + // |decode_cb_| and |reset_cb_| are replaced by every by Decode() and Reset(). DecodeCB decode_cb_; base::Closure reset_cb_;
diff --git a/media/mojo/clients/mojo_audio_decoder_unittest.cc b/media/mojo/clients/mojo_audio_decoder_unittest.cc index 44319b12..aa7b71d94 100644 --- a/media/mojo/clients/mojo_audio_decoder_unittest.cc +++ b/media/mojo/clients/mojo_audio_decoder_unittest.cc
@@ -18,6 +18,7 @@ #include "media/base/media_util.h" #include "media/base/mock_filters.h" #include "media/base/test_helpers.h" +#include "media/base/waiting.h" #include "media/mojo/clients/mojo_audio_decoder.h" #include "media/mojo/interfaces/audio_decoder.mojom.h" #include "media/mojo/services/mojo_audio_decoder_service.h" @@ -78,6 +79,7 @@ // Completion callbacks. MOCK_METHOD1(OnInitialized, void(bool)); MOCK_METHOD1(OnOutput, void(const scoped_refptr<AudioBuffer>&)); + MOCK_METHOD1(OnWaiting, void(WaitingReason)); MOCK_METHOD1(OnDecoded, void(DecodeStatus)); MOCK_METHOD0(OnReset, void()); @@ -109,7 +111,8 @@ mock_audio_decoder_ = mock_audio_decoder.get(); EXPECT_CALL(*mock_audio_decoder_, Initialize(_, _, _, _, _)) - .WillRepeatedly(DoAll(SaveArg<3>(&output_cb_), RunCallback<2>(true))); + .WillRepeatedly(DoAll(SaveArg<3>(&output_cb_), SaveArg<4>(&waiting_cb_), + RunCallback<2>(true))); EXPECT_CALL(*mock_audio_decoder_, Decode(_, _)) .WillRepeatedly( DoAll(InvokeWithoutArgs(this, &MojoAudioDecoderTest::ReturnOutput), @@ -141,7 +144,7 @@ base::Bind(&MojoAudioDecoderTest::OnInitialized, base::Unretained(this)), base::Bind(&MojoAudioDecoderTest::OnOutput, base::Unretained(this)), - base::NullCallback()); + base::Bind(&MojoAudioDecoderTest::OnWaiting, base::Unretained(this))); RunLoop(); } @@ -178,6 +181,8 @@ } } + void WaitForKey() { waiting_cb_.Run(WaitingReason::kNoDecryptionKey); } + void DecodeMultipleTimes(int num_of_decodes) { num_of_decodes_ = num_of_decodes; KeepDecodingOrQuit(); @@ -218,6 +223,7 @@ std::unique_ptr<MojoAudioDecoder> mojo_audio_decoder_; MojoCdmServiceContext mojo_cdm_service_context_; AudioDecoder::OutputCB output_cb_; + WaitingCB waiting_cb_; AudioTimestampHelper input_timestamp_helper_; // The thread where the service runs. This provides test coverage in an @@ -275,6 +281,19 @@ DecodeAndReset(); } +TEST_F(MojoAudioDecoderTest, WaitingForKey) { + Initialize(); + EXPECT_CALL(*mock_audio_decoder_, Decode(_, _)) + .WillOnce( + DoAll(InvokeWithoutArgs(this, &MojoAudioDecoderTest::WaitForKey), + RunCallback<1>(DecodeStatus::OK))); + EXPECT_CALL(*this, OnWaiting(WaitingReason::kNoDecryptionKey)).Times(1); + EXPECT_CALL(*this, OnDecoded(DecodeStatus::OK)) + .WillOnce(InvokeWithoutArgs(this, &MojoAudioDecoderTest::QuitLoop)); + Decode(); + RunLoop(); +} + // TODO(xhwang): Add more tests. } // namespace media
diff --git a/media/mojo/clients/mojo_video_decoder.cc b/media/mojo/clients/mojo_video_decoder.cc index 4ffbde6b..3568e9d 100644 --- a/media/mojo/clients/mojo_video_decoder.cc +++ b/media/mojo/clients/mojo_video_decoder.cc
@@ -116,7 +116,7 @@ CdmContext* cdm_context, const InitCB& init_cb, const OutputCB& output_cb, - const WaitingCB& /* waiting_cb */) { + const WaitingCB& waiting_cb) { DVLOG(1) << __func__; DCHECK(task_runner_->BelongsToCurrentThread()); @@ -155,6 +155,8 @@ initialized_ = false; init_cb_ = init_cb; output_cb_ = output_cb; + waiting_cb_ = waiting_cb; + remote_decoder_->Initialize( config, low_delay, cdm_id, base::Bind(&MojoVideoDecoder::OnInitializeDone, base::Unretained(this))); @@ -321,9 +323,18 @@ std::move(command_buffer_id), target_color_space_); } +void MojoVideoDecoder::OnWaiting(WaitingReason reason) { + DVLOG(2) << __func__; + DCHECK(task_runner_->BelongsToCurrentThread()); + + waiting_cb_.Run(reason); +} + void MojoVideoDecoder::RequestOverlayInfo(bool restart_for_transitions) { DVLOG(2) << __func__; + DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(request_overlay_info_cb_); + overlay_info_requested_ = true; request_overlay_info_cb_.Run( restart_for_transitions, @@ -333,6 +344,8 @@ void MojoVideoDecoder::OnOverlayInfoChanged(const OverlayInfo& overlay_info) { DVLOG(2) << __func__; + DCHECK(task_runner_->BelongsToCurrentThread()); + if (has_connection_error_) return; remote_decoder_->OnOverlayInfoChanged(overlay_info);
diff --git a/media/mojo/clients/mojo_video_decoder.h b/media/mojo/clients/mojo_video_decoder.h index 5d59225..a3db308 100644 --- a/media/mojo/clients/mojo_video_decoder.h +++ b/media/mojo/clients/mojo_video_decoder.h
@@ -63,6 +63,7 @@ const scoped_refptr<VideoFrame>& frame, bool can_read_without_stalling, const base::Optional<base::UnguessableToken>& release_token) final; + void OnWaiting(WaitingReason reason) final; void RequestOverlayInfo(bool restart_for_transitions) final; void set_writer_capacity_for_testing(uint32_t capacity) { @@ -98,6 +99,7 @@ InitCB init_cb_; OutputCB output_cb_; + WaitingCB waiting_cb_; uint64_t decode_counter_ = 0; std::map<uint64_t, DecodeCB> pending_decodes_; base::Closure reset_cb_;
diff --git a/media/mojo/interfaces/audio_decoder.mojom b/media/mojo/interfaces/audio_decoder.mojom index 4ee086b..6836240 100644 --- a/media/mojo/interfaces/audio_decoder.mojom +++ b/media/mojo/interfaces/audio_decoder.mojom
@@ -42,4 +42,8 @@ interface AudioDecoderClient { // Sends the decoded audio buffer back to the proxy. OnBufferDecoded(AudioBuffer buffer); + + // Called when the remote decoder is waiting because of |reason|, e.g. waiting + // for decryption key. + OnWaiting(WaitingReason reason); };
diff --git a/media/mojo/interfaces/video_decoder.mojom b/media/mojo/interfaces/video_decoder.mojom index 1e3ff82c..3b70b99 100644 --- a/media/mojo/interfaces/video_decoder.mojom +++ b/media/mojo/interfaces/video_decoder.mojom
@@ -151,6 +151,10 @@ bool can_read_without_stalling, mojo_base.mojom.UnguessableToken? release_token); + // Called when the remote decoder is waiting because of |reason|, e.g. waiting + // for decryption key. + OnWaiting(WaitingReason reason); + // Request to be notified when the current OverlayInfo changes. This results // in at least one call to OnOverlayInfoChanged() for the initial OverlayInfo. // |restart_for_transitions| sets whether the decoder should be restarted on
diff --git a/media/mojo/services/mojo_audio_decoder_service.cc b/media/mojo/services/mojo_audio_decoder_service.cc index 15cae7c5..eba8b65 100644 --- a/media/mojo/services/mojo_audio_decoder_service.cc +++ b/media/mojo/services/mojo_audio_decoder_service.cc
@@ -57,7 +57,7 @@ base::Bind(&MojoAudioDecoderService::OnInitialized, weak_this_, base::Passed(&callback)), base::Bind(&MojoAudioDecoderService::OnAudioBufferReady, weak_this_), - base::NullCallback()); + base::Bind(&MojoAudioDecoderService::OnWaiting, weak_this_)); } void MojoAudioDecoderService::SetDataSource( @@ -140,4 +140,9 @@ client_->OnBufferDecoded(mojom::AudioBuffer::From(audio_buffer)); } +void MojoAudioDecoderService::OnWaiting(WaitingReason reason) { + DVLOG(1) << __func__; + client_->OnWaiting(reason); +} + } // namespace media
diff --git a/media/mojo/services/mojo_audio_decoder_service.h b/media/mojo/services/mojo_audio_decoder_service.h index 58fce42..2cb52f4 100644 --- a/media/mojo/services/mojo_audio_decoder_service.h +++ b/media/mojo/services/mojo_audio_decoder_service.h
@@ -59,6 +59,10 @@ // Called by |decoder_| for each decoded buffer. void OnAudioBufferReady(const scoped_refptr<AudioBuffer>& audio_buffer); + // Called by |decoder_| when it's waiting because of |reason|, e.g. waiting + // for decryption key. + void OnWaiting(WaitingReason reason); + std::unique_ptr<MojoDecoderBufferReader> mojo_decoder_buffer_reader_; // A helper object required to get CDM from CDM id.
diff --git a/media/mojo/services/mojo_video_decoder_service.cc b/media/mojo/services/mojo_video_decoder_service.cc index e7a1159..4ec54f1 100644 --- a/media/mojo/services/mojo_video_decoder_service.cc +++ b/media/mojo/services/mojo_video_decoder_service.cc
@@ -207,13 +207,12 @@ DCHECK(cdm_context); } + using Self = MojoVideoDecoderService; decoder_->Initialize( config, low_delay, cdm_context, - base::BindRepeating(&MojoVideoDecoderService::OnDecoderInitialized, - weak_this_), - base::BindRepeating(&MojoVideoDecoderService::OnDecoderOutput, - weak_this_), - base::NullCallback()); + base::BindRepeating(&Self::OnDecoderInitialized, weak_this_), + base::BindRepeating(&Self::OnDecoderOutput, weak_this_), + base::BindRepeating(&Self::OnDecoderWaiting, weak_this_)); } void MojoVideoDecoderService::Decode(mojom::DecoderBufferPtr buffer, @@ -358,6 +357,14 @@ std::move(release_token)); } +void MojoVideoDecoderService::OnDecoderWaiting(WaitingReason reason) { + DVLOG(3) << __func__; + DCHECK(client_); + TRACE_EVENT1("media", "MojoVideoDecoderService::OnDecoderWaiting", "reason", + static_cast<int>(reason)); + client_->OnWaiting(reason); +} + void MojoVideoDecoderService::OnOverlayInfoChanged( const OverlayInfo& overlay_info) { DVLOG(2) << __func__;
diff --git a/media/mojo/services/mojo_video_decoder_service.h b/media/mojo/services/mojo_video_decoder_service.h index 72f52386..bb33a0fd 100644 --- a/media/mojo/services/mojo_video_decoder_service.h +++ b/media/mojo/services/mojo_video_decoder_service.h
@@ -76,6 +76,8 @@ void OnDecoderReset(); void OnDecoderOutput(const scoped_refptr<VideoFrame>& frame); + void OnDecoderWaiting(WaitingReason reason); + void OnDecoderRequestedOverlayInfo( bool restart_for_transitions, const ProvideOverlayInfoCB& provide_overlay_info_cb);
diff --git a/media/mojo/test/mojo_video_decoder_integration_test.cc b/media/mojo/test/mojo_video_decoder_integration_test.cc index 18b48a7..851d68a 100644 --- a/media/mojo/test/mojo_video_decoder_integration_test.cc +++ b/media/mojo/test/mojo_video_decoder_integration_test.cc
@@ -21,12 +21,14 @@ #include "gpu/command_buffer/common/mailbox_holder.h" #include "media/base/decode_status.h" #include "media/base/decoder_buffer.h" +#include "media/base/decrypt_config.h" #include "media/base/gmock_callback_support.h" #include "media/base/media_log.h" #include "media/base/mock_media_log.h" #include "media/base/test_helpers.h" #include "media/base/video_decoder.h" #include "media/base/video_frame.h" +#include "media/base/waiting.h" #include "media/mojo/clients/mojo_video_decoder.h" #include "media/mojo/services/mojo_cdm_service_context.h" #include "media/mojo/services/mojo_media_client.h" @@ -86,9 +88,10 @@ CdmContext* /* cdm_context */, const InitCB& init_cb, const OutputCB& output_cb, - const WaitingCB& /* waiting_cb */) override { + const WaitingCB& waiting_cb) override { config_ = config; output_cb_ = output_cb; + waiting_cb_ = waiting_cb; DoInitialize(init_cb); } @@ -115,15 +118,22 @@ void DoDecode(scoped_refptr<DecoderBuffer> buffer, const DecodeCB& decode_cb) { if (!buffer->end_of_stream()) { - gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes]; - mailbox_holders[0].mailbox.name[0] = 1; - scoped_refptr<VideoFrame> frame = VideoFrame::WrapNativeTextures( - PIXEL_FORMAT_ARGB, mailbox_holders, GetReleaseMailboxCB(), - config_.coded_size(), config_.visible_rect(), config_.natural_size(), - buffer->timestamp()); - frame->metadata()->SetBoolean(VideoFrameMetadata::POWER_EFFICIENT, true); - output_cb_.Run(frame); + if (buffer->decrypt_config()) { + // Simulate the case where outputs are only returned when key arrives. + waiting_cb_.Run(WaitingReason::kNoDecryptionKey); + } else { + gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes]; + mailbox_holders[0].mailbox.name[0] = 1; + scoped_refptr<VideoFrame> frame = VideoFrame::WrapNativeTextures( + PIXEL_FORMAT_ARGB, mailbox_holders, GetReleaseMailboxCB(), + config_.coded_size(), config_.visible_rect(), + config_.natural_size(), buffer->timestamp()); + frame->metadata()->SetBoolean(VideoFrameMetadata::POWER_EFFICIENT, + true); + output_cb_.Run(frame); + } } + // |decode_cb| must not be called from the same stack. base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(decode_cb, DecodeStatus::OK)); @@ -142,6 +152,7 @@ VideoDecoderConfig config_; OutputCB output_cb_; + WaitingCB waiting_cb_; DISALLOW_COPY_AND_ASSIGN(MockVideoDecoder); }; @@ -221,7 +232,7 @@ EXPECT_CALL(init_cb, Run(_)).WillOnce(SaveArg<0>(&result)); client_->Initialize(TestVideoConfig::NormalH264(), false, nullptr, - init_cb.Get(), output_cb_.Get(), base::NullCallback()); + init_cb.Get(), output_cb_.Get(), waiting_cb_.Get()); RunUntilIdle(); return result; @@ -261,9 +272,27 @@ return buffer; } + // TODO(xhwang): Add a function to help create encrypted video buffers in + // media/base/test_helpers.h. + scoped_refptr<DecoderBuffer> CreateEncryptedKeyframe(int64_t timestamp_ms) { + auto buffer = CreateKeyframe(timestamp_ms); + + const uint8_t kFakeKeyId[] = {0x4b, 0x65, 0x79, 0x20, 0x49, 0x44}; + const uint8_t kFakeIv[DecryptConfig::kDecryptionKeySize] = {0}; + buffer->set_decrypt_config(DecryptConfig::CreateCencConfig( + std::string(reinterpret_cast<const char*>(kFakeKeyId), + arraysize(kFakeKeyId)), + std::string(reinterpret_cast<const char*>(kFakeIv), arraysize(kFakeIv)), + {})); + + return buffer; + } + // Callback that |client_| will deliver VideoFrames to. StrictMock<base::MockCallback<VideoDecoder::OutputCB>> output_cb_; + StrictMock<base::MockCallback<WaitingCB>> waiting_cb_; + // MojoVideoDecoder (client) under test. std::unique_ptr<MojoVideoDecoder> client_; @@ -332,7 +361,7 @@ // Clear |decoder_| so that Initialize() should fail. decoder_.reset(); client_->Initialize(TestVideoConfig::NormalH264(), false, nullptr, - init_cb.Get(), output_cb_.Get(), base::NullCallback()); + init_cb.Get(), output_cb_.Get(), waiting_cb_.Get()); RunUntilIdle(); } @@ -345,7 +374,7 @@ // CdmContext* (3rd parameter) is not provided but the VideoDecoderConfig // specifies encrypted video, so Initialize() should fail. client_->Initialize(TestVideoConfig::NormalEncrypted(), false, nullptr, - init_cb.Get(), output_cb_.Get(), base::NullCallback()); + init_cb.Get(), output_cb_.Get(), waiting_cb_.Get()); RunUntilIdle(); } @@ -356,6 +385,20 @@ RunUntilIdle(); } +TEST_F(MojoVideoDecoderIntegrationTest, WaitingForKey) { + ASSERT_TRUE(Initialize()); + + auto buffer = CreateEncryptedKeyframe(0); + StrictMock<base::MockCallback<VideoDecoder::DecodeCB>> decode_cb; + + EXPECT_CALL(*decoder_, Decode(_, _)); + EXPECT_CALL(waiting_cb_, Run(WaitingReason::kNoDecryptionKey)); + EXPECT_CALL(decode_cb, Run(DecodeStatus::OK)); + + client_->Decode(buffer, decode_cb.Get()); + RunUntilIdle(); +} + TEST_F(MojoVideoDecoderIntegrationTest, Decode) { ASSERT_TRUE(Initialize()); @@ -408,7 +451,7 @@ EXPECT_CALL(*decoder_, DidGetReleaseMailboxCB()).Times(AtLeast(0)); EXPECT_CALL(output_cb_, Run(_)).Times(kMaxDecodeRequests); EXPECT_CALL(*decoder_, Decode(_, _)).Times(kMaxDecodeRequests); - EXPECT_CALL(*decoder_, Reset(_)).Times(1); + EXPECT_CALL(*decoder_, Reset(_)); InSequence s; // Make sure all callbacks are fired in order. EXPECT_CALL(decode_cb, Run(_)).Times(kMaxDecodeRequests); @@ -436,7 +479,7 @@ EXPECT_CALL(*decoder_, DidGetReleaseMailboxCB()).Times(AtLeast(0)); EXPECT_CALL(output_cb_, Run(_)).Times(kMaxDecodeRequests); EXPECT_CALL(*decoder_, Decode(_, _)).Times(kMaxDecodeRequests); - EXPECT_CALL(*decoder_, Reset(_)).Times(1); + EXPECT_CALL(*decoder_, Reset(_)); InSequence s; // Make sure all callbacks are fired in order. EXPECT_CALL(decode_cb, Run(_)).Times(kMaxDecodeRequests);
diff --git a/net/base/network_config_watcher_mac.cc b/net/base/network_config_watcher_mac.cc index 4e3f5e83..f324969a 100644 --- a/net/base/network_config_watcher_mac.cc +++ b/net/base/network_config_watcher_mac.cc
@@ -115,6 +115,8 @@ } #endif // !defined(OS_IOS) +} // namespace + class NetworkConfigWatcherMacThread : public base::Thread { public: NetworkConfigWatcherMacThread(NetworkConfigWatcherMac::Delegate* delegate); @@ -154,10 +156,8 @@ } NetworkConfigWatcherMacThread::~NetworkConfigWatcherMacThread() { - // Allow IO because Stop() calls PlatformThread::Join(), which is a blocking - // operation. This is expected during shutdown. - base::ThreadRestrictions::ScopedAllowIO allow_io; - + // This is expected to be invoked during shutdown. + base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_thread_join; Stop(); } @@ -259,8 +259,6 @@ return true; } -} // namespace - NetworkConfigWatcherMac::NetworkConfigWatcherMac(Delegate* delegate) : notifier_thread_(new NetworkConfigWatcherMacThread(delegate)) { // We create this notifier thread because the notification implementation
diff --git a/net/proxy_resolution/multi_threaded_proxy_resolver.cc b/net/proxy_resolution/multi_threaded_proxy_resolver.cc index c05969df..ae41f4f 100644 --- a/net/proxy_resolution/multi_threaded_proxy_resolver.cc +++ b/net/proxy_resolution/multi_threaded_proxy_resolver.cc
@@ -28,6 +28,11 @@ #include "net/proxy_resolution/proxy_resolver.h" namespace net { + +// http://crbug.com/69710 +class MultiThreadedProxyResolverScopedAllowJoinOnIO + : public base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope {}; + namespace { class Job; @@ -370,8 +375,9 @@ DCHECK(coordinator_); { - // See http://crbug.com/69710. - base::ThreadRestrictions::ScopedAllowIO allow_io; + // TODO(http://crbug.com/69710): Use TaskScheduler instead of creating a + // base::Thread. + MultiThreadedProxyResolverScopedAllowJoinOnIO allow_thread_join; // Join the worker thread. thread_.reset();
diff --git a/net/proxy_resolution/proxy_config_service_android.cc b/net/proxy_resolution/proxy_config_service_android.cc index 3dcbfab..6134fd88 100644 --- a/net/proxy_resolution/proxy_config_service_android.cc +++ b/net/proxy_resolution/proxy_config_service_android.cc
@@ -199,6 +199,73 @@ } } +std::string ParseOverrideRules( + const std::vector<ProxyConfigServiceAndroid::ProxyOverrideRule>& + override_rules, + ProxyConfig::ProxyRules* proxy_rules) { + // If no rules were specified, use DIRECT for everything. + if (override_rules.empty()) { + DCHECK(proxy_rules->empty()); + return ""; + } + + // Otherwise use a proxy list per URL scheme. + proxy_rules->type = ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME; + + for (const auto& rule : override_rules) { + // Parse the proxy URL. + ProxyServer proxy_server = + ProxyServer::FromURI(rule.proxy_url, ProxyServer::Scheme::SCHEME_HTTP); + if (!proxy_server.is_valid()) { + return "Invalid Proxy URL: " + rule.proxy_url; + } else if (proxy_server.is_quic()) { + return "Unsupported proxy scheme: " + rule.proxy_url; + } + + // Parse the URL scheme. + if (base::EqualsCaseInsensitiveASCII(rule.url_scheme, "http")) { + proxy_rules->proxies_for_http.AddProxyServer(proxy_server); + } else if (base::EqualsCaseInsensitiveASCII(rule.url_scheme, "https")) { + proxy_rules->proxies_for_https.AddProxyServer(proxy_server); + } else if (rule.url_scheme == "*") { + proxy_rules->fallback_proxies.AddProxyServer(proxy_server); + } else { + return "Unsupported URL scheme: " + rule.url_scheme; + } + } + + // If there is no per-URL scheme distinction simplify the ProxyRules. + if (proxy_rules->proxies_for_http.IsEmpty() && + proxy_rules->proxies_for_https.IsEmpty() && + !proxy_rules->fallback_proxies.IsEmpty()) { + proxy_rules->type = ProxyConfig::ProxyRules::Type::PROXY_LIST; + std::swap(proxy_rules->single_proxies, proxy_rules->fallback_proxies); + } + + return ""; +} + +std::string CreateOverrideProxyConfig( + const std::vector<ProxyConfigServiceAndroid::ProxyOverrideRule>& + proxy_rules, + const std::vector<std::string>& bypass_rules, + ProxyConfigWithAnnotation* config) { + ProxyConfig proxy_config; + auto result = ParseOverrideRules(proxy_rules, &proxy_config.proxy_rules()); + if (!result.empty()) { + return result; + } + + for (const auto& bypass_rule : bypass_rules) { + if (!proxy_config.proxy_rules().bypass_rules.AddRuleFromString( + bypass_rule)) { + return "Invalid bypass rule " + bypass_rule; + } + } + *config = ProxyConfigWithAnnotation(proxy_config, NO_TRAFFIC_ANNOTATION_YET); + return ""; +} + } // namespace class ProxyConfigServiceAndroid::Delegate @@ -302,19 +369,28 @@ } // Called in the JNI sequence. - void SetProxyOverride(const std::string& host, - int port, - const std::vector<std::string>& exclusion_list, - base::OnceClosure callback) { + std::string SetProxyOverride( + const std::vector<ProxyOverrideRule>& proxy_rules, + const std::vector<std::string>& bypass_rules, + base::OnceClosure callback) { DCHECK(InJNISequence()); has_proxy_override_ = true; + + // Creates a new proxy config ProxyConfigWithAnnotation proxy_config; - CreateStaticProxyConfig(host, port, "", exclusion_list, &proxy_config); + std::string result = + CreateOverrideProxyConfig(proxy_rules, bypass_rules, &proxy_config); + if (!result.empty()) { + return result; + } + network_task_runner_->PostTaskAndReply( FROM_HERE, base::BindOnce(&Delegate::SetNewConfigInNetworkSequence, this, proxy_config), std::move(callback)); + + return ""; } // Called in the JNI sequence. @@ -457,12 +533,12 @@ delegate_->ProxySettingsChanged(); } -void ProxyConfigServiceAndroid::SetProxyOverride( - const std::string& host, - int port, - const std::vector<std::string>& exclusion_list, +std::string ProxyConfigServiceAndroid::SetProxyOverride( + const std::vector<ProxyOverrideRule>& proxy_rules, + const std::vector<std::string>& bypass_rules, base::OnceClosure callback) { - delegate_->SetProxyOverride(host, port, exclusion_list, std::move(callback)); + return delegate_->SetProxyOverride(proxy_rules, bypass_rules, + std::move(callback)); } void ProxyConfigServiceAndroid::ClearProxyOverride(base::OnceClosure callback) {
diff --git a/net/proxy_resolution/proxy_config_service_android.h b/net/proxy_resolution/proxy_config_service_android.h index 55394552..5a5a15f 100644 --- a/net/proxy_resolution/proxy_config_service_android.h +++ b/net/proxy_resolution/proxy_config_service_android.h
@@ -76,10 +76,34 @@ ConfigAvailability GetLatestProxyConfig( ProxyConfigWithAnnotation* config) override; - void SetProxyOverride(const std::string& host, - int port, - const std::vector<std::string>& exclusion_list, - base::OnceClosure callback); + // Holds a single proxy_url and the scheme for which it should be used. + // If url_scheme is "*", this proxy will be used for all schemes. + // The proxy_url is a string in the format: [scheme://] host [:port] for + // a proxy or "direct://" for direct. Scheme is optional and will default to + // HTTP; port is optional and defaults to 80 for HTTP, 443 for HTTPS and QUIC, + // and 1080 for SOCKS. Host must be one of: + // - IPv6 literal with brackets + // - IPv4 literal + // - A label or labels separated by periods + struct ProxyOverrideRule { + ProxyOverrideRule(const std::string& url_scheme, + const std::string& proxy_url) + : url_scheme(url_scheme), proxy_url(proxy_url) {} + + std::string url_scheme; + std::string proxy_url; + }; + + // Receives a list of ProxyOverrideRule and a list of strings for bypass + // rules. Wildcards are accepted. URLs that match any pattern in any bypass + // rule will go to DIRECT. "<local>" and "<-loopback>" are also accepted. + // If no errors were found, returns an empty string, otherwise an UTF-8 string + // with a description of the error that was found. + // Callback is called (asynchronously) if input was valid. + std::string SetProxyOverride( + const std::vector<ProxyOverrideRule>& proxy_rules, + const std::vector<std::string>& bypass_rules, + base::OnceClosure callback); void ClearProxyOverride(base::OnceClosure callback); private:
diff --git a/net/proxy_resolution/proxy_config_service_android_unittest.cc b/net/proxy_resolution/proxy_config_service_android_unittest.cc index 61ece7dd..33c45cb 100644 --- a/net/proxy_resolution/proxy_config_service_android_unittest.cc +++ b/net/proxy_resolution/proxy_config_service_android_unittest.cc
@@ -110,11 +110,20 @@ EXPECT_EQ(expected, proxy_info.ToPacString()); } - void SetProxyOverride(const std::string& host, - int port, - const std::vector<std::string>& exclusion_list, - base::OnceClosure callback) { - service_.SetProxyOverride(host, port, exclusion_list, std::move(callback)); + void SetProxyOverride( + const ProxyConfigServiceAndroid::ProxyOverrideRule& rule, + const std::vector<std::string>& bypass_rules, + base::OnceClosure callback) { + std::vector<ProxyConfigServiceAndroid::ProxyOverrideRule> rules; + rules.push_back(rule); + SetProxyOverride(rules, bypass_rules, std::move(callback)); + } + + void SetProxyOverride( + const std::vector<ProxyConfigServiceAndroid::ProxyOverrideRule>& rules, + const std::vector<std::string>& bypass_rules, + base::OnceClosure callback) { + service_.SetProxyOverride(rules, bypass_rules, std::move(callback)); base::RunLoop().RunUntilIdle(); } @@ -199,30 +208,113 @@ EXPECT_TRUE(proxyCallback.called); } -TEST_F(ProxyConfigServiceAndroidTest, TestOverrideNoProxy) { - std::vector<std::string> exclusion_list; +TEST_F(ProxyConfigServiceAndroidTest, TestProxyOverrideSchemes) { + std::vector<std::string> bypass_rules; // Check that webview uses the default proxy TestMapping("http://example.com/", "DIRECT"); + TestMapping("https://example.com/", "DIRECT"); + TestMapping("ftp://example.com/", "DIRECT"); - // Check that webview uses the custom proxy - SetProxyOverride("httpoverrideproxy.com", 200, exclusion_list, + SetProxyOverride({"*", "httpoverrideproxy.com:200"}, bypass_rules, base::DoNothing()); TestMapping("http://example.com/", "PROXY httpoverrideproxy.com:200"); + TestMapping("https://example.com/", "PROXY httpoverrideproxy.com:200"); + TestMapping("ftp://example.com/", "PROXY httpoverrideproxy.com:200"); + + // Check that webview uses the custom proxy only for https + SetProxyOverride({"https", "httpoverrideproxy.com:200"}, bypass_rules, + base::DoNothing()); + TestMapping("http://example.com/", "DIRECT"); + TestMapping("https://example.com/", "PROXY httpoverrideproxy.com:200"); + TestMapping("ftp://example.com/", "DIRECT"); // Check that webview uses the default proxy ClearProxyOverride(base::DoNothing()); TestMapping("http://example.com/", "DIRECT"); + TestMapping("https://example.com/", "DIRECT"); + TestMapping("ftp://example.com/", "DIRECT"); +} + +TEST_F(ProxyConfigServiceAndroidTest, TestProxyOverridePorts) { + std::vector<std::string> bypass_rules; + + // Check that webview uses the default proxy + TestMapping("http://example.com/", "DIRECT"); + TestMapping("https://example.com/", "DIRECT"); + TestMapping("ftp://example.com/", "DIRECT"); + + // Check that webview uses port 80 for http proxies + SetProxyOverride({"*", "httpoverrideproxy.com"}, bypass_rules, + base::DoNothing()); + TestMapping("http://example.com:444", "PROXY httpoverrideproxy.com:80"); + TestMapping("https://example.com:2222", "PROXY httpoverrideproxy.com:80"); + TestMapping("ftp://example.com:15", "PROXY httpoverrideproxy.com:80"); + + // Check that webview uses port 443 for https proxies + SetProxyOverride({"*", "https://httpoverrideproxy.com"}, bypass_rules, + base::DoNothing()); + TestMapping("http://example.com:8080", "HTTPS httpoverrideproxy.com:443"); + TestMapping("https://example.com:1111", "HTTPS httpoverrideproxy.com:443"); + TestMapping("ftp://example.com:752", "HTTPS httpoverrideproxy.com:443"); + + // Check that webview uses custom port + SetProxyOverride({"*", "https://httpoverrideproxy.com:777"}, bypass_rules, + base::DoNothing()); + TestMapping("http://example.com:8080", "HTTPS httpoverrideproxy.com:777"); + TestMapping("https://example.com:1111", "HTTPS httpoverrideproxy.com:777"); + TestMapping("ftp://example.com:752", "HTTPS httpoverrideproxy.com:777"); + + ClearProxyOverride(base::DoNothing()); +} + +TEST_F(ProxyConfigServiceAndroidTest, TestProxyOverrideMultipleRules) { + std::vector<std::string> bypass_rules; + + // Multiple rules with schemes are valid + std::vector<ProxyConfigServiceAndroid::ProxyOverrideRule> rules; + rules.push_back({"http", "httpoverrideproxy.com"}); + rules.push_back({"https", "https://httpoverrideproxy.com"}); + SetProxyOverride(rules, bypass_rules, base::DoNothing()); + TestMapping("https://example.com/", "HTTPS httpoverrideproxy.com:443"); + TestMapping("http://example.com/", "PROXY httpoverrideproxy.com:80"); + + // Rules with and without scheme can be combined + rules.clear(); + rules.push_back({"http", "overrideproxy1.com"}); + rules.push_back({"*", "overrideproxy2.com"}); + SetProxyOverride(rules, bypass_rules, base::DoNothing()); + TestMapping("https://example.com/", "PROXY overrideproxy2.com:80"); + TestMapping("http://example.com/", "PROXY overrideproxy1.com:80"); + + ClearProxyOverride(base::DoNothing()); +} + +TEST_F(ProxyConfigServiceAndroidTest, TestProxyOverrideListOfRules) { + std::vector<std::string> bypass_rules; + + std::vector<ProxyConfigServiceAndroid::ProxyOverrideRule> rules; + rules.push_back({"http", "httpproxy1"}); + rules.push_back({"*", "socks5://fallback1"}); + rules.push_back({"http", "httpproxy2"}); + rules.push_back({"*", "fallback2"}); + rules.push_back({"*", "direct://"}); + SetProxyOverride(rules, bypass_rules, base::DoNothing()); + + TestMapping("http://example.com", "PROXY httpproxy1:80;PROXY httpproxy2:80"); + TestMapping("https://example.com", + "SOCKS5 fallback1:1080;PROXY fallback2:80;DIRECT"); } TEST_F(ProxyConfigServiceAndroidTest, TestOverrideAndProxy) { - std::vector<std::string> exclusion_list; + std::vector<std::string> bypass_rules; + bypass_rules.push_back("www.excluded.com"); // Check that webview uses the default proxy TestMapping("http://example.com/", "DIRECT"); // Check that webview uses the custom proxy - SetProxyOverride("httpoverrideproxy.com", 200, exclusion_list, + SetProxyOverride({"*", "httpoverrideproxy.com:200"}, bypass_rules, base::DoNothing()); TestMapping("http://example.com/", "PROXY httpoverrideproxy.com:200"); @@ -230,6 +322,7 @@ AddProperty("http.proxyHost", "httpsomeproxy.com"); ProxySettingsChanged(); TestMapping("http://example.com/", "PROXY httpoverrideproxy.com:200"); + TestMapping("http://www.excluded.com/", "DIRECT"); // Check that webview uses the non default proxy ClearProxyOverride(base::DoNothing()); @@ -237,7 +330,7 @@ } TEST_F(ProxyConfigServiceAndroidTest, TestProxyAndOverride) { - std::vector<std::string> exclusion_list; + std::vector<std::string> bypass_rules; // Check that webview uses the default proxy TestMapping("http://example.com/", "DIRECT"); @@ -248,7 +341,7 @@ TestMapping("http://example.com/", "PROXY httpsomeproxy.com:80"); // Check that webview uses the custom proxy - SetProxyOverride("httpoverrideproxy.com", 200, exclusion_list, + SetProxyOverride({"*", "httpoverrideproxy.com:200"}, bypass_rules, base::DoNothing()); TestMapping("http://example.com/", "PROXY httpoverrideproxy.com:200"); @@ -258,13 +351,13 @@ } TEST_F(ProxyConfigServiceAndroidTest, TestOverrideThenProxy) { - std::vector<std::string> exclusion_list; + std::vector<std::string> bypass_rules; // Check that webview uses the default proxy TestMapping("http://example.com/", "DIRECT"); // Check that webview uses the custom proxy - SetProxyOverride("httpoverrideproxy.com", 200, exclusion_list, + SetProxyOverride({"*", "httpoverrideproxy.com:200"}, bypass_rules, base::DoNothing()); TestMapping("http://example.com/", "PROXY httpoverrideproxy.com:200"); @@ -279,7 +372,7 @@ } TEST_F(ProxyConfigServiceAndroidTest, TestClearOverride) { - std::vector<std::string> exclusion_list; + std::vector<std::string> bypass_rules; // Check that webview uses the default proxy TestMapping("http://example.com/", "DIRECT"); @@ -290,7 +383,7 @@ } TEST_F(ProxyConfigServiceAndroidTest, TestProxyAndClearOverride) { - std::vector<std::string> exclusion_list; + std::vector<std::string> bypass_rules; // Check that webview uses the non default proxy AddProperty("http.proxyHost", "httpsomeproxy.com"); @@ -302,16 +395,16 @@ TestMapping("http://example.com/", "PROXY httpsomeproxy.com:80"); } -TEST_F(ProxyConfigServiceAndroidTest, TestOverrideExclusionList) { - std::vector<std::string> exclusion_list; - exclusion_list.push_back("excluded.com"); +TEST_F(ProxyConfigServiceAndroidTest, TestOverrideBypassRules) { + std::vector<std::string> bypass_rules; + bypass_rules.push_back("excluded.com"); // Check that webview uses the default proxy TestMapping("http://excluded.com/", "DIRECT"); TestMapping("http://example.com/", "DIRECT"); - // Check that webview handles the exclusion list correctly - SetProxyOverride("httpoverrideproxy.com", 200, exclusion_list, + // Check that webview handles the bypass rules correctly + SetProxyOverride({"*", "httpoverrideproxy.com:200"}, bypass_rules, base::DoNothing()); TestMapping("http://excluded.com/", "DIRECT"); TestMapping("http://example.com/", "PROXY httpoverrideproxy.com:200"); @@ -322,6 +415,22 @@ TestMapping("http://example.com/", "DIRECT"); } +TEST_F(ProxyConfigServiceAndroidTest, TestOverrideToDirect) { + std::vector<std::string> bypass_rules; + + // Check that webview uses the non default proxy + AddProperty("http.proxyHost", "httpsomeproxy.com"); + ProxySettingsChanged(); + TestMapping("http://example.com/", "PROXY httpsomeproxy.com:80"); + + // Check that webview uses no proxy + TestMapping("http://example.com/", "PROXY httpsomeproxy.com:80"); + SetProxyOverride({"*", "direct://"}, bypass_rules, base::DoNothing()); + TestMapping("http://example.com/", "DIRECT"); + + ClearProxyOverride(base::DoNothing()); +} + // !! The following test cases are automatically generated from // !! net/android/tools/proxy_test_cases.py. // !! Please edit that file instead of editing the test cases below and
diff --git a/net/proxy_resolution/proxy_resolver_v8_tracing.cc b/net/proxy_resolution/proxy_resolver_v8_tracing.cc index 9a751c2..5a635a9 100644 --- a/net/proxy_resolution/proxy_resolver_v8_tracing.cc +++ b/net/proxy_resolution/proxy_resolver_v8_tracing.cc
@@ -49,6 +49,9 @@ // known. namespace net { +class ScopedAllowThreadJoinForProxyResolverV8Tracing + : public base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope {}; + namespace { // Upper bound on how many *unique* DNS resolves a PAC script is allowed @@ -943,7 +946,7 @@ CHECK_EQ(0, num_outstanding_callbacks_); // Join the worker thread. See http://crbug.com/69710. - base::ThreadRestrictions::ScopedAllowIO allow_io; + ScopedAllowThreadJoinForProxyResolverV8Tracing allow_thread_join; thread_.reset(); } @@ -1060,7 +1063,7 @@ void StopWorkerThread() { // Join the worker thread. See http://crbug.com/69710. - base::ThreadRestrictions::ScopedAllowIO allow_io; + ScopedAllowThreadJoinForProxyResolverV8Tracing allow_thread_join; thread_.reset(); }
diff --git a/net/test/embedded_test_server/embedded_test_server.cc b/net/test/embedded_test_server/embedded_test_server.cc index 371e73ab0..6578877c 100644 --- a/net/test/embedded_test_server/embedded_test_server.cc +++ b/net/test/embedded_test_server/embedded_test_server.cc
@@ -67,9 +67,7 @@ } { - // Thread::Join induced by test code should cause an assert. - base::ScopedAllowBlockingForTesting allow_blocking; - + base::ScopedAllowBaseSyncPrimitivesForTesting allow_wait_for_thread_join; io_thread_.reset(); } }
diff --git a/net/test/spawned_test_server/local_test_server_win.cc b/net/test/spawned_test_server/local_test_server_win.cc index 5addf0be..bc78e77c 100644 --- a/net/test/spawned_test_server/local_test_server_win.cc +++ b/net/test/spawned_test_server/local_test_server_win.cc
@@ -72,7 +72,7 @@ bytes_read += num_bytes; } - base::ScopedAllowBlockingForTesting allow_thread_join; + base::ScopedAllowBaseSyncPrimitivesForTesting allow_thread_join; thread.Stop(); // If the timeout kicked in, abort.
diff --git a/remoting/protocol/channel_socket_adapter.cc b/remoting/protocol/channel_socket_adapter.cc index 7e22b67..5922be7 100644 --- a/remoting/protocol/channel_socket_adapter.cc +++ b/remoting/protocol/channel_socket_adapter.cc
@@ -126,7 +126,7 @@ rtc::PacketTransportInterface* transport, const char* data, size_t data_size, - const rtc::PacketTime& packet_time, + const int64_t& packet_time, int flags) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK_EQ(transport, channel_);
diff --git a/remoting/protocol/channel_socket_adapter.h b/remoting/protocol/channel_socket_adapter.h index 1a68d69..763103d 100644 --- a/remoting/protocol/channel_socket_adapter.h +++ b/remoting/protocol/channel_socket_adapter.h
@@ -59,7 +59,7 @@ void OnNewPacket(rtc::PacketTransportInterface* transport, const char* data, size_t data_size, - const rtc::PacketTime& packet_time, + const int64_t& packet_time, int flags); void OnWritableState(rtc::PacketTransportInterface* transport); void OnChannelDestroyed(cricket::IceTransportInternal* ice_transport);
diff --git a/remoting/protocol/chromium_socket_factory_unittest.cc b/remoting/protocol/chromium_socket_factory_unittest.cc index 328c18c..bcac36f 100644 --- a/remoting/protocol/chromium_socket_factory_unittest.cc +++ b/remoting/protocol/chromium_socket_factory_unittest.cc
@@ -35,9 +35,10 @@ } void OnPacket(rtc::AsyncPacketSocket* socket, - const char* data, size_t size, + const char* data, + size_t size, const rtc::SocketAddress& address, - const rtc::PacketTime& packet_time) { + const int64_t& packet_time) { EXPECT_EQ(socket, socket_.get()); last_packet_.assign(data, data + size); last_address_ = address;
diff --git a/remoting/protocol/webrtc_transport.cc b/remoting/protocol/webrtc_transport.cc index a4c78bc..9cc6152e 100644 --- a/remoting/protocol/webrtc_transport.cc +++ b/remoting/protocol/webrtc_transport.cc
@@ -44,6 +44,9 @@ namespace remoting { namespace protocol { +class ScopedAllowThreadJoinForWebRtcTransport + : public base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope {}; + namespace { // Delay after candidate creation before sending transport-info message to @@ -248,10 +251,9 @@ } ~PeerConnectionWrapper() override { - // PeerConnection creates threads internally, which are stopped when the - // connection is closed. Thread.Stop() is a blocking operation. - // See crbug.com/660081. - base::ThreadRestrictions::ScopedAllowIO allow_io; + // PeerConnection creates threads internally, which are joined when the + // connection is closed. See crbug.com/660081. + ScopedAllowThreadJoinForWebRtcTransport allow_thread_join; peer_connection_->Close(); peer_connection_ = nullptr; peer_connection_factory_ = nullptr;
diff --git a/remoting/resources/remoting_strings_it.xtb b/remoting/resources/remoting_strings_it.xtb index dc2e4e67..edb58b0 100644 --- a/remoting/resources/remoting_strings_it.xtb +++ b/remoting/resources/remoting_strings_it.xtb
@@ -24,7 +24,7 @@ <translation id="1520828917794284345">Adatta dimensioni desktop</translation> <translation id="154040539590487450">Impossibile avviare il servizio di accesso remoto.</translation> <translation id="1546934824884762070">Si è verificato un errore imprevisto. Segnala il problema agli sviluppatori.</translation> -<translation id="1624185583382384493">Chrome Remote Desktop è ora sul Web. Prova la nostra <ph name="LINK_BEGIN" />app web<ph name="LINK_END" /> è veloce e gratuita, con ancora più funzionalità, tra cui il supporto migliorato di più monitor.</translation> +<translation id="1624185583382384493">Chrome Remote Desktop è ora sul Web. Prova la nostra <ph name="LINK_BEGIN" />app web<ph name="LINK_END" />: è veloce e gratuita, con ancora più funzionalità, tra cui il supporto migliorato di più monitor.</translation> <translation id="1643640058022401035">Se esci da questa pagina, la sessione Chromoting verrà terminata.</translation> <translation id="1654128982815600832">Attivazione connessioni remote per questo computer in corso…</translation> <translation id="170207782578677537">Impossibile registrare il computer.</translation>
diff --git a/remoting/resources/remoting_strings_sw.xtb b/remoting/resources/remoting_strings_sw.xtb index e73c597b..d5982c9 100644 --- a/remoting/resources/remoting_strings_sw.xtb +++ b/remoting/resources/remoting_strings_sw.xtb
@@ -24,7 +24,7 @@ <translation id="1520828917794284345">Badilisha ukubwa wa eneo-kazi ili litoshe</translation> <translation id="154040539590487450">Imeshindwa kuanza huduma ya ufikiaji wa mbali.</translation> <translation id="1546934824884762070">Hitilafu isiyotarajiwa imetokea. Tafadhali ripoti tatizo hili kwa wasanidi programu.</translation> -<translation id="1624185583382384493">Programu ya Chrome ya Ufikiaji wa Kompyuta kutoka Mbali sasa iko kwenye wavuti. Jaribu <ph name="LINK_BEGIN" />programu yetu ya wavuti<ph name="LINK_END" />—ina kasi na hailipishwi, ina vipengele vingi zaidi, ikiwa ni pamoja na uwezo ulioboreshwa wa kutumia skrini nyingi.</translation> +<translation id="1624185583382384493">Programu ya Chrome ya Ufikiaji wa Kompyuta kutoka Mbali sasa inapatikana kwenye wavuti. Jaribu <ph name="LINK_BEGIN" />programu yetu ya wavuti<ph name="LINK_END" />—ina kasi na hailipishwi, ina vipengele vingi zaidi, ikiwa ni pamoja na uwezo ulioboreshwa wa kutumia skrini nyingi.</translation> <translation id="1643640058022401035">Kuondoka kwenye ukurasa huu kutakamilisha kipindi chako cha Chromoting.</translation> <translation id="1654128982815600832">Inawasha miunganisho ya mbali kwa kompyuta hii...</translation> <translation id="170207782578677537">Ilishindwa kusajili kompyuta hii.</translation>
diff --git a/services/audio/public/cpp/output_device.cc b/services/audio/public/cpp/output_device.cc index 3ccc6e9..0944f87 100644 --- a/services/audio/public/cpp/output_device.cc +++ b/services/audio/public/cpp/output_device.cc
@@ -82,7 +82,7 @@ void OutputDevice::OnConnectionError() { // Connection errors should be rare and handling them synchronously is // simpler. - base::ScopedAllowBlocking allow_blocking; + base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_thread_join; CleanUp(); }
diff --git a/services/audio/stream_factory.cc b/services/audio/stream_factory.cc index eb7d7d28..dfced4c 100644 --- a/services/audio/stream_factory.cc +++ b/services/audio/stream_factory.cc
@@ -127,7 +127,7 @@ // See //chromecast/media/cast_audio_manager.h for more information. const std::string device_id_or_group_id = #if defined(IS_CHROMECAST) - group_id.ToString(); + (group_id.ToString().empty()) ? output_device_id : group_id.ToString(); #else output_device_id; #endif
diff --git a/services/identity/identity_manager_impl_unittest.cc b/services/identity/identity_manager_impl_unittest.cc index 6f947f59..9d2c6bcf 100644 --- a/services/identity/identity_manager_impl_unittest.cc +++ b/services/identity/identity_manager_impl_unittest.cc
@@ -42,7 +42,7 @@ : signin_client_(&pref_service_), token_service_(&pref_service_), #if defined(OS_CHROMEOS) - signin_manager_(&signin_client_, &token_service_, &account_tracker_), + signin_manager_(&signin_client_, &account_tracker_), #else signin_manager_(&signin_client_, &token_service_,
diff --git a/services/identity/public/cpp/accounts_mutator.cc b/services/identity/public/cpp/accounts_mutator.cc index 6fce82d9..a80285a1 100644 --- a/services/identity/public/cpp/accounts_mutator.cc +++ b/services/identity/public/cpp/accounts_mutator.cc
@@ -4,10 +4,18 @@ #include "services/identity/public/cpp/accounts_mutator.h" +#include "components/signin/core/browser/profile_oauth2_token_service.h" + namespace identity { -AccountsMutator::AccountsMutator(ProfileOAuth2TokenService* token_service) {} +AccountsMutator::AccountsMutator(ProfileOAuth2TokenService* token_service) + : token_service_(token_service) {} AccountsMutator::~AccountsMutator() {} +void AccountsMutator::LoadAccountsFromDisk( + const std::string& primary_account_id) { + token_service_->LoadCredentials(primary_account_id); +} + } // namespace identity
diff --git a/services/identity/public/cpp/accounts_mutator.h b/services/identity/public/cpp/accounts_mutator.h index 08d0dbc..471be5b3 100644 --- a/services/identity/public/cpp/accounts_mutator.h +++ b/services/identity/public/cpp/accounts_mutator.h
@@ -20,7 +20,22 @@ explicit AccountsMutator(ProfileOAuth2TokenService* token_service); ~AccountsMutator(); + // Loads credentials from a backing persistent store to make them available + // after service is used between profile restarts. + // + // The primary account is specified with the |primary_account_id| argument. + // For a regular profile, the primary account id comes from IdentityManager. + // For a supervised user, the id comes from SupervisedUserService. + // NOTE: In normal usage this method SHOULD NOT be called as the loading of + // accounts from disk occurs as part of the internal startup flow. The method + // is only used in production for a very small number of corner case startup + // flows. + // TODO(https://crbug.com/740117): Eliminate the need to expose this. + void LoadAccountsFromDisk(const std::string& primary_account_id); + private: + ProfileOAuth2TokenService* token_service_; + DISALLOW_COPY_AND_ASSIGN(AccountsMutator); };
diff --git a/services/identity/public/cpp/accounts_mutator_unittest.cc b/services/identity/public/cpp/accounts_mutator_unittest.cc index 0b71e1d..36e7ffc8 100644 --- a/services/identity/public/cpp/accounts_mutator_unittest.cc +++ b/services/identity/public/cpp/accounts_mutator_unittest.cc
@@ -66,8 +66,17 @@ DISALLOW_COPY_AND_ASSIGN(AccountsMutatorTest); }; -TEST_F(AccountsMutatorTest, Basic) { - // Should not crash. +// Tests that requesting a load of accounts results in the notification +// firing that tokens were loaded. +TEST_F(AccountsMutatorTest, LoadAccountsFromDisk) { + base::RunLoop run_loop; + token_service_observer()->set_on_refresh_tokens_loaded_callback( + run_loop.QuitClosure()); + + // Load the accounts and ensure that we see the resulting notification that + // they were loaded. + accounts_mutator()->LoadAccountsFromDisk(""); + run_loop.Run(); } } // namespace identity
diff --git a/services/identity/public/cpp/identity_manager.h b/services/identity/public/cpp/identity_manager.h index d4c5e23..5beebe4 100644 --- a/services/identity/public/cpp/identity_manager.h +++ b/services/identity/public/cpp/identity_manager.h
@@ -33,12 +33,18 @@ class UserSessionManager; } +// Necessary to declare this class as a friend. +namespace file_manager { +class MultiProfileFilesAppBrowserTest; +} + namespace network { class SharedURLLoaderFactory; } // Necessary to declare these classes as friends. class ArcSupportHostTest; +class MultiProfileDownloadNotificationTest; namespace identity { @@ -310,6 +316,7 @@ const std::string& account_id); friend void RemoveRefreshTokenForAccount(IdentityManager* identity_manager, const std::string& account_id); + friend bool AreAllCredentialsLoaded(IdentityManager* identity_manager); friend void UpdateAccountInfoForAccount(IdentityManager* identity_manager, AccountInfo account_info); friend void UpdatePersistentErrorOfRefreshTokenForAccount( @@ -317,6 +324,9 @@ const std::string& account_id, const GoogleServiceAuthError& auth_error); + friend MultiProfileDownloadNotificationTest; + friend file_manager::MultiProfileFilesAppBrowserTest; + // These clients needs to call SetPrimaryAccountSynchronously(). friend ArcSupportHostTest; friend arc::ArcTermsOfServiceDefaultNegotiatorTest;
diff --git a/services/identity/public/cpp/identity_manager_unittest.cc b/services/identity/public/cpp/identity_manager_unittest.cc index 8c8e31b..aa3f169 100644 --- a/services/identity/public/cpp/identity_manager_unittest.cc +++ b/services/identity/public/cpp/identity_manager_unittest.cc
@@ -466,7 +466,7 @@ DCHECK_EQ(account_consistency, signin::AccountConsistencyMethod::kDisabled) << "AccountConsistency is not used by SigninManagerBase"; signin_manager_ = std::make_unique<FakeSigninManagerBase>( - &signin_client_, &token_service_, &account_tracker_); + &signin_client_, &account_tracker_); #else signin_manager_ = std::make_unique<FakeSigninManager>( &signin_client_, &token_service_, &account_tracker_,
diff --git a/services/identity/public/cpp/identity_test_environment.cc b/services/identity/public/cpp/identity_test_environment.cc index 76f8b57..99cef72 100644 --- a/services/identity/public/cpp/identity_test_environment.cc +++ b/services/identity/public/cpp/identity_test_environment.cc
@@ -67,7 +67,7 @@ signin_client_(pref_service()), token_service_(pref_service()), #if defined(OS_CHROMEOS) - signin_manager_(&signin_client_, &token_service_, &account_tracker_) { + signin_manager_(&signin_client_, &account_tracker_) { #else signin_manager_(&signin_client_, &token_service_,
diff --git a/services/identity/public/cpp/identity_test_utils.cc b/services/identity/public/cpp/identity_test_utils.cc index 183281a..c7521dd 100644 --- a/services/identity/public/cpp/identity_test_utils.cc +++ b/services/identity/public/cpp/identity_test_utils.cc
@@ -308,6 +308,10 @@ run_loop.Run(); } +bool AreAllCredentialsLoaded(IdentityManager* identity_manager) { + return identity_manager->GetTokenService()->AreAllCredentialsLoaded(); +} + void SetCookieAccounts(FakeGaiaCookieManagerService* cookie_manager, IdentityManager* identity_manager, const std::vector<CookieParams>& cookie_accounts) {
diff --git a/services/identity/public/cpp/identity_test_utils.h b/services/identity/public/cpp/identity_test_utils.h index 9023437..d530444 100644 --- a/services/identity/public/cpp/identity_test_utils.h +++ b/services/identity/public/cpp/identity_test_utils.h
@@ -119,6 +119,9 @@ void RemoveRefreshTokenForAccount(IdentityManager* identity_manager, const std::string& account_id); +// Returns true if all credentials have been loaded from disk. +bool AreAllCredentialsLoaded(IdentityManager* identity_manager); + // Puts the given accounts into the Gaia cookie, replacing any previous // accounts. Blocks until the accounts have been set. // NOTE: See disclaimer at top of file re: direct usage.
diff --git a/services/media_session/audio_focus_manager.cc b/services/media_session/audio_focus_manager.cc index f0049df..c775811 100644 --- a/services/media_session/audio_focus_manager.cc +++ b/services/media_session/audio_focus_manager.cc
@@ -119,6 +119,15 @@ return request; } + void BindToController(mojom::MediaControllerRequest request) { + if (!controller_) { + controller_ = std::make_unique<MediaController>(); + controller_->SetMediaSession(session_.get()); + } + + controller_->BindToInterface(std::move(request)); + } + private: void SetSessionInfo(mojom::MediaSessionInfoPtr session_info) { bool is_controllable_changed = @@ -154,6 +163,8 @@ AudioFocusManagerMetricsHelper metrics_helper_; bool encountered_error_ = false; + std::unique_ptr<MediaController> controller_; + mojom::MediaSessionPtr session_; mojom::MediaSessionInfoPtr session_info_; mojom::AudioFocusType audio_focus_type_; @@ -277,6 +288,24 @@ bindings_.dispatch_context()->source_name = name; } +void AudioFocusManager::CreateActiveMediaController( + mojom::MediaControllerRequest request) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + active_media_controller_.BindToInterface(std::move(request)); +} + +void AudioFocusManager::CreateMediaControllerForSession( + mojom::MediaControllerRequest request, + const base::UnguessableToken& request_id) { + for (auto& row : audio_focus_stack_) { + if (row->id() != request_id) + continue; + + row->BindToController(std::move(request)); + break; + } +} + void AudioFocusManager::BindToInterface( mojom::AudioFocusManagerRequest request) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -290,10 +319,10 @@ debug_bindings_.AddBinding(this, std::move(request)); } -void AudioFocusManager::BindToActiveControllerInterface( - mojom::MediaControllerRequest request) { +void AudioFocusManager::BindToControllerManagerInterface( + mojom::MediaControllerManagerRequest request) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - active_media_controller_.BindToInterface(std::move(request)); + controller_bindings_.AddBinding(this, std::move(request)); } void AudioFocusManager::RequestAudioFocusInternal(
diff --git a/services/media_session/audio_focus_manager.h b/services/media_session/audio_focus_manager.h index 0aba74d..810f5fd 100644 --- a/services/media_session/audio_focus_manager.h +++ b/services/media_session/audio_focus_manager.h
@@ -31,7 +31,8 @@ class MediaController; class AudioFocusManager : public mojom::AudioFocusManager, - public mojom::AudioFocusManagerDebug { + public mojom::AudioFocusManagerDebug, + public mojom::MediaControllerManager { public: AudioFocusManager(); ~AudioFocusManager() override; @@ -59,14 +60,22 @@ void GetDebugInfoForRequest(const RequestId& request_id, GetDebugInfoForRequestCallback callback) override; + // mojom::MediaControllerManager. + void CreateActiveMediaController( + mojom::MediaControllerRequest request) override; + void CreateMediaControllerForSession( + mojom::MediaControllerRequest request, + const base::UnguessableToken& request_id) override; + // Bind to a mojom::AudioFocusManagerRequest. void BindToInterface(mojom::AudioFocusManagerRequest request); // Bind to a mojom::AudioFocusManagerDebugRequest. void BindToDebugInterface(mojom::AudioFocusManagerDebugRequest request); - // Bind to a mojom::MediaControllerRequest. - void BindToActiveControllerInterface(mojom::MediaControllerRequest request); + // Bind to a mojom::MediaControllerManagerRequest. + void BindToControllerManagerInterface( + mojom::MediaControllerManagerRequest request); private: friend class AudioFocusManagerTest; @@ -117,6 +126,9 @@ // Holds mojo bindings for the Audio Focus Manager Debug API. mojo::BindingSet<mojom::AudioFocusManagerDebug> debug_bindings_; + // Holds mojo bindings for the Media Controller Manager API. + mojo::BindingSet<mojom::MediaControllerManager> controller_bindings_; + // Weak reference of managed observers. Observers are expected to remove // themselves before being destroyed. mojo::InterfacePtrSet<mojom::AudioFocusObserver> observers_;
diff --git a/services/media_session/manifest.json b/services/media_session/manifest.json index 98343bb..d9edfb6 100644 --- a/services/media_session/manifest.json +++ b/services/media_session/manifest.json
@@ -9,8 +9,8 @@ "provides": { "app": [ "media_session.mojom.AudioFocusManager", - "media_session.mojom.AudioFocusManagerDebug", - "media_session.mojom.MediaController" + "media_session.mojom.AudioFocusManagerDebug", + "media_session.mojom.MediaControllerManager" ], "tests": [ "*" ] }
diff --git a/services/media_session/media_controller.cc b/services/media_session/media_controller.cc index a102d1d7..4d48b59 100644 --- a/services/media_session/media_controller.cc +++ b/services/media_session/media_controller.cc
@@ -57,6 +57,7 @@ if (!session_info_.is_null()) observer->MediaSessionInfoChanged(session_info_.Clone()); observer->MediaSessionMetadataChanged(session_metadata_); + observer->MediaSessionActionsChanged(session_actions_); observers_.AddPtr(std::move(observer)); } @@ -82,6 +83,17 @@ session_metadata_ = metadata; } +void MediaController::MediaSessionActionsChanged( + const std::vector<mojom::MediaSessionAction>& actions) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + observers_.ForAllPtrs([&actions](mojom::MediaSessionObserver* observer) { + observer->MediaSessionActionsChanged(actions); + }); + + session_actions_ = actions; +} + void MediaController::PreviousTrack() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -112,6 +124,7 @@ session_binding_.Close(); session_info_.reset(); session_metadata_.reset(); + session_actions_.clear(); if (session) { // Add |this| as an observer for |session|.
diff --git a/services/media_session/media_controller.h b/services/media_session/media_controller.h index 3490288..0cf05d70 100644 --- a/services/media_session/media_controller.h +++ b/services/media_session/media_controller.h
@@ -43,6 +43,8 @@ mojom::MediaSessionInfoPtr session_info) override; void MediaSessionMetadataChanged( const base::Optional<MediaMetadata>&) override; + void MediaSessionActionsChanged( + const std::vector<mojom::MediaSessionAction>& action) override; // Sets the media session that the controller should be bound to. If the // session is already bound to the same session then we will return false. @@ -61,6 +63,9 @@ // The current metadata for |session_|. base::Optional<MediaMetadata> session_metadata_; + // The current actions for |session_|. + std::vector<mojom::MediaSessionAction> session_actions_; + // Raw pointer to the local proxy. This is used for sending control events to // the underlying MediaSession. mojom::MediaSession* session_ = nullptr;
diff --git a/services/media_session/media_controller_unittest.cc b/services/media_session/media_controller_unittest.cc index e9e810b..c92e5c9 100644 --- a/services/media_session/media_controller_unittest.cc +++ b/services/media_session/media_controller_unittest.cc
@@ -12,6 +12,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_task_environment.h" #include "base/time/time.h" +#include "base/unguessable_token.h" #include "services/media_session/media_session_service.h" #include "services/media_session/public/cpp/media_metadata.h" #include "services/media_session/public/cpp/test/mock_media_session.h" @@ -32,7 +33,11 @@ connector_factory_.GetDefaultConnector()->BindInterface(mojom::kServiceName, &audio_focus_ptr_); connector_factory_.GetDefaultConnector()->BindInterface( - mojom::kServiceName, &media_controller_ptr_); + mojom::kServiceName, &controller_manager_ptr_); + + controller_manager_ptr_->CreateActiveMediaController( + mojo::MakeRequest(&media_controller_ptr_)); + controller_manager_ptr_.FlushForTesting(); } void TearDown() override { @@ -47,12 +52,17 @@ mojom::MediaControllerPtr& controller() { return media_controller_ptr_; } + mojom::MediaControllerManagerPtr& manager() { + return controller_manager_ptr_; + } + private: base::test::ScopedTaskEnvironment task_environment_; service_manager::TestConnectorFactory connector_factory_; std::unique_ptr<MediaSessionService> service_; mojom::AudioFocusManagerPtr audio_focus_ptr_; mojom::MediaControllerPtr media_controller_ptr_; + mojom::MediaControllerManagerPtr controller_manager_ptr_; DISALLOW_COPY_AND_ASSIGN(MediaControllerTest); }; @@ -619,4 +629,202 @@ } } +TEST_F(MediaControllerTest, BoundController_Routing) { + test::MockMediaSession media_session_1; + test::MockMediaSession media_session_2; + + media_session_1.SetIsControllable(true); + media_session_2.SetIsControllable(true); + + { + test::MockMediaSessionMojoObserver observer(media_session_1); + RequestAudioFocus(media_session_1, mojom::AudioFocusType::kGain); + observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying); + } + + mojom::MediaControllerPtr controller; + manager()->CreateMediaControllerForSession( + mojo::MakeRequest(&controller), media_session_1.GetRequestIdFromClient()); + manager().FlushForTesting(); + + EXPECT_EQ(0, media_session_1.next_track_count()); + + controller->NextTrack(); + controller.FlushForTesting(); + + EXPECT_EQ(1, media_session_1.next_track_count()); + + { + test::MockMediaSessionMojoObserver observer(media_session_2); + RequestAudioFocus(media_session_2, mojom::AudioFocusType::kGain); + observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying); + } + + EXPECT_EQ(1, media_session_1.next_track_count()); + EXPECT_EQ(0, media_session_2.next_track_count()); + + controller->NextTrack(); + controller.FlushForTesting(); + + EXPECT_EQ(2, media_session_1.next_track_count()); + EXPECT_EQ(0, media_session_2.next_track_count()); +} + +TEST_F(MediaControllerTest, BoundController_BadRequestId) { + test::MockMediaSession media_session; + media_session.SetIsControllable(true); + + { + test::MockMediaSessionMojoObserver observer(media_session); + RequestAudioFocus(media_session, mojom::AudioFocusType::kGain); + observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying); + } + + mojom::MediaControllerPtr controller; + manager()->CreateMediaControllerForSession(mojo::MakeRequest(&controller), + base::UnguessableToken::Create()); + manager().FlushForTesting(); + + EXPECT_EQ(0, media_session.next_track_count()); + + controller->NextTrack(); + controller.FlushForTesting(); + + EXPECT_EQ(0, media_session.next_track_count()); +} + +TEST_F(MediaControllerTest, BoundController_DropOnAbandon) { + test::MockMediaSession media_session; + media_session.SetIsControllable(true); + + { + test::MockMediaSessionMojoObserver observer(media_session); + RequestAudioFocus(media_session, mojom::AudioFocusType::kGain); + observer.WaitForPlaybackState(mojom::MediaPlaybackState::kPlaying); + } + + mojom::MediaControllerPtr controller; + manager()->CreateMediaControllerForSession( + mojo::MakeRequest(&controller), media_session.GetRequestIdFromClient()); + manager().FlushForTesting(); + + EXPECT_EQ(0, media_session.next_track_count()); + + controller->NextTrack(); + controller.FlushForTesting(); + + EXPECT_EQ(1, media_session.next_track_count()); + + media_session.AbandonAudioFocusFromClient(); + + EXPECT_EQ(1, media_session.next_track_count()); + + controller->NextTrack(); + controller.FlushForTesting(); + + EXPECT_EQ(1, media_session.next_track_count()); +} + +TEST_F(MediaControllerTest, ActiveController_Actions_AddObserver_Empty) { + test::MockMediaSession media_session; + media_session.SetIsControllable(true); + + { + test::MockMediaSessionMojoObserver observer(media_session); + RequestAudioFocus(media_session, mojom::AudioFocusType::kGain); + observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive); + } + + { + test::MockMediaSessionMojoObserver observer(controller()); + observer.WaitForActions(); + EXPECT_TRUE(observer.actions().empty()); + } +} + +TEST_F(MediaControllerTest, ActiveController_Actions_AddObserver_WithInfo) { + test::MockMediaSession media_session; + media_session.SetIsControllable(true); + + { + test::MockMediaSessionMojoObserver observer(media_session); + RequestAudioFocus(media_session, mojom::AudioFocusType::kGain); + observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive); + } + + media_session.EnableAction(mojom::MediaSessionAction::kPlay); + + { + test::MockMediaSessionMojoObserver observer(controller()); + observer.WaitForActions(); + + EXPECT_EQ(1u, observer.actions().size()); + EXPECT_EQ(mojom::MediaSessionAction::kPlay, observer.actions()[0]); + } +} + +TEST_F(MediaControllerTest, ActiveController_Actions_Observer_Empty) { + test::MockMediaSession media_session; + media_session.EnableAction(mojom::MediaSessionAction::kPlay); + media_session.SetIsControllable(true); + + { + test::MockMediaSessionMojoObserver observer(media_session); + RequestAudioFocus(media_session, mojom::AudioFocusType::kGain); + observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive); + } + + { + test::MockMediaSessionMojoObserver observer(controller()); + observer.WaitForActions(); + + media_session.DisableAction(mojom::MediaSessionAction::kPlay); + observer.WaitForActions(); + + EXPECT_TRUE(observer.actions().empty()); + } +} + +TEST_F(MediaControllerTest, ActiveController_Actions_Observer_WithInfo) { + test::MockMediaSession media_session; + media_session.SetIsControllable(true); + + { + test::MockMediaSessionMojoObserver observer(media_session); + RequestAudioFocus(media_session, mojom::AudioFocusType::kGain); + observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive); + } + + { + test::MockMediaSessionMojoObserver observer(controller()); + observer.WaitForActions(); + + media_session.EnableAction(mojom::MediaSessionAction::kPlay); + observer.WaitForActions(); + + EXPECT_EQ(1u, observer.actions().size()); + EXPECT_EQ(mojom::MediaSessionAction::kPlay, observer.actions()[0]); + } +} + +TEST_F(MediaControllerTest, ActiveController_Actions_Observer_Abandoned) { + test::MockMediaSession media_session; + media_session.EnableAction(mojom::MediaSessionAction::kPlay); + media_session.SetIsControllable(true); + + { + test::MockMediaSessionMojoObserver observer(media_session); + RequestAudioFocus(media_session, mojom::AudioFocusType::kGain); + observer.WaitForState(mojom::MediaSessionInfo::SessionState::kActive); + } + + media_session.AbandonAudioFocusFromClient(); + + { + test::MockMediaSessionMojoObserver observer(controller()); + observer.WaitForActions(); + EXPECT_TRUE(observer.actions().empty()); + } +} + } // namespace media_session
diff --git a/services/media_session/media_session_service.cc b/services/media_session/media_session_service.cc index 352892b1..a40f7d2 100644 --- a/services/media_session/media_session_service.cc +++ b/services/media_session/media_session_service.cc
@@ -20,7 +20,7 @@ base::BindRepeating(&AudioFocusManager::BindToDebugInterface, base::Unretained(audio_focus_manager_.get()))); registry_.AddInterface( - base::BindRepeating(&AudioFocusManager::BindToActiveControllerInterface, + base::BindRepeating(&AudioFocusManager::BindToControllerManagerInterface, base::Unretained(audio_focus_manager_.get()))); }
diff --git a/services/media_session/public/cpp/test/mock_media_session.cc b/services/media_session/public/cpp/test/mock_media_session.cc index 0f3d166..e846f799 100644 --- a/services/media_session/public/cpp/test/mock_media_session.cc +++ b/services/media_session/public/cpp/test/mock_media_session.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "base/stl_util.h" #include "services/media_session/public/cpp/switches.h" namespace media_session { @@ -35,7 +36,7 @@ if (wanted_state_ == session_info_->state || session_info_->playback_state == wanted_playback_state_) { - run_loop_.Quit(); + run_loop_->Quit(); } } @@ -44,21 +45,31 @@ session_metadata_ = metadata; if (waiting_for_metadata_) { - run_loop_.Quit(); + run_loop_->Quit(); waiting_for_metadata_ = false; } else if (waiting_for_non_empty_metadata_ && metadata.has_value()) { - run_loop_.Quit(); + run_loop_->Quit(); waiting_for_non_empty_metadata_ = false; } } +void MockMediaSessionMojoObserver::MediaSessionActionsChanged( + const std::vector<mojom::MediaSessionAction>& actions) { + session_actions_ = actions; + + if (waiting_for_actions_) { + run_loop_->Quit(); + waiting_for_actions_ = false; + } +} + void MockMediaSessionMojoObserver::WaitForState( mojom::MediaSessionInfo::SessionState wanted_state) { if (session_info_ && session_info_->state == wanted_state) return; wanted_state_ = wanted_state; - run_loop_.Run(); + StartWaiting(); } void MockMediaSessionMojoObserver::WaitForPlaybackState( @@ -67,14 +78,14 @@ return; wanted_playback_state_ = wanted_state; - run_loop_.Run(); + StartWaiting(); } const base::Optional<MediaMetadata>& MockMediaSessionMojoObserver::WaitForMetadata() { if (!session_metadata_.has_value()) { waiting_for_metadata_ = true; - run_loop_.Run(); + StartWaiting(); } return session_metadata_.value(); @@ -83,12 +94,25 @@ const MediaMetadata& MockMediaSessionMojoObserver::WaitForNonEmptyMetadata() { if (!session_metadata_.has_value() || !session_metadata_->has_value()) { waiting_for_non_empty_metadata_ = true; - run_loop_.Run(); + StartWaiting(); } return session_metadata_->value(); } +void MockMediaSessionMojoObserver::WaitForActions() { + waiting_for_actions_ = true; + StartWaiting(); +} + +void MockMediaSessionMojoObserver::StartWaiting() { + DCHECK(!run_loop_); + + run_loop_ = std::make_unique<base::RunLoop>(); + run_loop_->Run(); + run_loop_.reset(); +} + MockMediaSession::MockMediaSession() = default; MockMediaSession::MockMediaSession(bool force_duck) : force_duck_(force_duck) {} @@ -122,6 +146,11 @@ ++add_observer_count_; observer->MediaSessionInfoChanged(GetMediaSessionInfoSync()); + + std::vector<mojom::MediaSessionAction> actions(actions_.begin(), + actions_.end()); + observer->MediaSessionActionsChanged(actions); + observers_.AddPtr(std::move(observer)); } @@ -261,6 +290,22 @@ }); } +void MockMediaSession::EnableAction(mojom::MediaSessionAction action) { + if (base::ContainsKey(actions_, action)) + return; + + actions_.insert(action); + NotifyActionObservers(); +} + +void MockMediaSession::DisableAction(mojom::MediaSessionAction action) { + if (!base::ContainsKey(actions_, action)) + return; + + actions_.erase(action); + NotifyActionObservers(); +} + void MockMediaSession::SetState(mojom::MediaSessionInfo::SessionState state) { state_ = state; NotifyObservers(); @@ -293,5 +338,14 @@ return info; } +void MockMediaSession::NotifyActionObservers() { + std::vector<mojom::MediaSessionAction> actions(actions_.begin(), + actions_.end()); + + observers_.ForAllPtrs([&actions](mojom::MediaSessionObserver* observer) { + observer->MediaSessionActionsChanged(actions); + }); +} + } // namespace test } // namespace media_session
diff --git a/services/media_session/public/cpp/test/mock_media_session.h b/services/media_session/public/cpp/test/mock_media_session.h index a66ad3b..2312fc7 100644 --- a/services/media_session/public/cpp/test/mock_media_session.h +++ b/services/media_session/public/cpp/test/mock_media_session.h
@@ -38,11 +38,14 @@ void MediaSessionInfoChanged(mojom::MediaSessionInfoPtr session) override; void MediaSessionMetadataChanged( const base::Optional<MediaMetadata>& metadata) override; + void MediaSessionActionsChanged( + const std::vector<mojom::MediaSessionAction>& actions) override; void WaitForState(mojom::MediaSessionInfo::SessionState wanted_state); void WaitForPlaybackState(mojom::MediaPlaybackState wanted_state); const base::Optional<MediaMetadata>& WaitForMetadata(); const MediaMetadata& WaitForNonEmptyMetadata(); + void WaitForActions(); const mojom::MediaSessionInfoPtr& session_info() const { return session_info_; @@ -53,15 +56,24 @@ return session_metadata_; } + const std::vector<mojom::MediaSessionAction>& actions() const { + return session_actions_; + } + private: + void StartWaiting(); + mojom::MediaSessionInfoPtr session_info_; base::Optional<base::Optional<MediaMetadata>> session_metadata_; + std::vector<mojom::MediaSessionAction> session_actions_; bool waiting_for_metadata_ = false; bool waiting_for_non_empty_metadata_ = false; + bool waiting_for_actions_ = false; + base::Optional<mojom::MediaSessionInfo::SessionState> wanted_state_; base::Optional<mojom::MediaPlaybackState> wanted_playback_state_; - base::RunLoop run_loop_; + std::unique_ptr<base::RunLoop> run_loop_; mojo::Binding<mojom::MediaSessionObserver> binding_; }; @@ -112,6 +124,9 @@ void SimulateMetadataChanged(const base::Optional<MediaMetadata>& metadata); + void EnableAction(mojom::MediaSessionAction action); + void DisableAction(mojom::MediaSessionAction action); + int prev_track_count() const { return prev_track_count_; } int next_track_count() const { return next_track_count_; } int add_observer_count() const { return add_observer_count_; } @@ -121,6 +136,7 @@ void SetState(mojom::MediaSessionInfo::SessionState); void NotifyObservers(); mojom::MediaSessionInfoPtr GetMediaSessionInfoSync() const; + void NotifyActionObservers(); mojom::AudioFocusRequestClientPtr afr_client_; @@ -133,6 +149,8 @@ int add_observer_count_ = 0; int seek_count_ = 0; + std::set<mojom::MediaSessionAction> actions_; + mojom::MediaSessionInfo::SessionState state_ = mojom::MediaSessionInfo::SessionState::kInactive;
diff --git a/services/media_session/public/mojom/media_controller.mojom b/services/media_session/public/mojom/media_controller.mojom index 7d22ef6..07a854b3 100644 --- a/services/media_session/public/mojom/media_controller.mojom +++ b/services/media_session/public/mojom/media_controller.mojom
@@ -5,11 +5,24 @@ module media_session.mojom; import "mojo/public/mojom/base/time.mojom"; +import "mojo/public/mojom/base/unguessable_token.mojom"; import "services/media_session/public/mojom/media_session.mojom"; -// Controls a MediaSession. This will automatically route commands to the -// correct session if the audio focus changes. If the media session is -// not controllable then the commands will be no-ops. +interface MediaControllerManager { + // Creates a MediaController linked to a specific session with |request_id|. + // This should match the |request_id| from the AudioFocusRequestState. + CreateMediaControllerForSession( + MediaController& request, + mojo_base.mojom.UnguessableToken request_id); + + // Creates a MediaController linked to the active session. This will + // automatically route commands to the correct session if the active session + // changes. If there is no active session then commands will be no-ops. + CreateActiveMediaController(MediaController& request); +}; + +// Controls a MediaSession. If the media session is not controllable then the +// commands will be no-ops. interface MediaController { // Suspend the media session. Suspend();
diff --git a/services/media_session/public/mojom/media_session.mojom b/services/media_session/public/mojom/media_session.mojom index ff9a6800..c06c51e3 100644 --- a/services/media_session/public/mojom/media_session.mojom +++ b/services/media_session/public/mojom/media_session.mojom
@@ -100,6 +100,10 @@ // can be null to be reset, e.g. the media that was being played has been // stopped. MediaSessionMetadataChanged@1(MediaMetadata? metadata); + + // Called when the media session action list has changed. This tells the + // observer which actions can be used to control the session. + MediaSessionActionsChanged@2(array<MediaSessionAction> action); }; // A MediaSession manages the media session and audio focus for a given
diff --git a/services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.cc b/services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.cc index c82d44d..b545d681 100644 --- a/services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.cc +++ b/services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.cc
@@ -181,7 +181,9 @@ // /config/vulkan/icd.d are to used configure and access the GPU. options->paths_to_clone.push_back(base::FilePath("/system/lib")); options->paths_to_clone.push_back(base::FilePath("/dev/class/gpu")); - options->paths_to_clone.push_back(base::FilePath("/config/vulkan/icd.d")); + const auto vulkan_icd_path = base::FilePath("/config/vulkan/icd.d"); + if (base::PathExists(vulkan_icd_path)) + options->paths_to_clone.push_back(vulkan_icd_path); } if (service_directory_client_channel_) {
diff --git a/services/ws/BUILD.gn b/services/ws/BUILD.gn index 83a649d..b0f50ed 100644 --- a/services/ws/BUILD.gn +++ b/services/ws/BUILD.gn
@@ -60,6 +60,8 @@ "user_activity_monitor.cc", "user_activity_monitor.h", "window_delegate_impl.cc", + "window_occlusion_change_builder.cc", + "window_occlusion_change_builder.h", "window_properties.cc", "window_server_test_impl.cc", "window_server_test_impl.h",
diff --git a/services/ws/client_root.cc b/services/ws/client_root.cc index b5612f4..b9772f2a 100644 --- a/services/ws/client_root.cc +++ b/services/ws/client_root.cc
@@ -98,10 +98,9 @@ if (last_surface_size_in_pixels_ != size_in_pixels || !proxy_window->local_surface_id().has_value() || last_device_scale_factor_ != window_->layer()->device_scale_factor()) { - parent_local_surface_id_allocator_.GenerateId(); + window_->AllocateLocalSurfaceId(); proxy_window->set_local_surface_id( - parent_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation() - .local_surface_id()); + window_->GetLocalSurfaceIdAllocation().local_surface_id()); last_surface_size_in_pixels_ = size_in_pixels; last_device_scale_factor_ = window_->layer()->device_scale_factor(); }
diff --git a/services/ws/client_root.h b/services/ws/client_root.h index d96b872..6d0b1701 100644 --- a/services/ws/client_root.h +++ b/services/ws/client_root.h
@@ -11,7 +11,6 @@ #include "base/macros.h" #include "base/optional.h" #include "components/viz/common/surfaces/local_surface_id.h" -#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" #include "components/viz/host/host_frame_sink_client.h" #include "ui/aura/window_observer.h" #include "ui/aura/window_tree_host_observer.h" @@ -134,7 +133,6 @@ // and device scale factor at the time the LocalSurfaceId was generated. gfx::Size last_surface_size_in_pixels_; float last_device_scale_factor_ = 1.0f; - viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_; std::unique_ptr<aura::ClientSurfaceEmbedder> client_surface_embedder_;
diff --git a/services/ws/ime/ime_unittest.cc b/services/ws/ime/ime_unittest.cc index 778f7177..452acec 100644 --- a/services/ws/ime/ime_unittest.cc +++ b/services/ws/ime/ime_unittest.cc
@@ -118,6 +118,11 @@ ws::mojom::StartSessionDetails::New(); TestTextInputClient client(MakeRequest(&details->client)); details->input_method_request = MakeRequest(&input_method); + details->state = ws::mojom::TextInputState::New(); + details->state->text_input_type = ui::TEXT_INPUT_TYPE_TEXT; + details->state->text_input_mode = ui::TEXT_INPUT_MODE_DEFAULT; + details->state->text_direction = base::i18n::LEFT_TO_RIGHT; + details->state->text_input_flags = 0; ime_driver_->StartSession(std::move(details)); // Send character key event.
diff --git a/services/ws/ime/test_ime_driver/test_ime_driver.cc b/services/ws/ime/test_ime_driver/test_ime_driver.cc index 7af4866..5ecfbb61 100644 --- a/services/ws/ime/test_ime_driver/test_ime_driver.cc +++ b/services/ws/ime/test_ime_driver/test_ime_driver.cc
@@ -20,7 +20,8 @@ private: // mojom::InputMethod: - void OnTextInputTypeChanged(ui::TextInputType text_input_type) override { + void OnTextInputStateChanged( + ws::mojom::TextInputStatePtr text_input_state) override { NOTIMPLEMENTED(); } void OnCaretBoundsChanged(const gfx::Rect& caret_bounds) override {
diff --git a/services/ws/public/mojom/ime/ime.mojom b/services/ws/public/mojom/ime/ime.mojom index b6c9bdb..b81c56d9 100644 --- a/services/ws/public/mojom/ime/ime.mojom +++ b/services/ws/public/mojom/ime/ime.mojom
@@ -112,16 +112,21 @@ kSearch, }; +// Represents the text input state of a client. +struct TextInputState { + ui.mojom.TextInputType text_input_type; + TextInputMode text_input_mode; + mojo_base.mojom.TextDirection text_direction; + int32 text_input_flags; // A bitfield of ui::TextInputFlags. +}; + // Parameters needed to start an IME session. struct StartSessionDetails { TextInputClient client; InputMethod& input_method_request; // Initial details about |client| required by IMEDriver. - ui.mojom.TextInputType text_input_type; - TextInputMode text_input_mode; - mojo_base.mojom.TextDirection text_direction; - int32 text_input_flags; + TextInputState state; gfx.mojom.Rect caret_bounds; }; @@ -143,7 +148,8 @@ // This interface is provided by IME drivers, and also by Mus as a lightweight // proxy between IME drivers and clients. interface InputMethod { - OnTextInputTypeChanged(ui.mojom.TextInputType text_input_type); + // Called when the text input state of client is changed. + OnTextInputStateChanged(TextInputState text_input_state); // Client sends |caret_bounds| in focused window coordinates, // Mus translates it to global coordinates and sends it to IME app.
diff --git a/services/ws/public/mojom/window_tree.mojom b/services/ws/public/mojom/window_tree.mojom index 14b857d..6c433ce 100644 --- a/services/ws/public/mojom/window_tree.mojom +++ b/services/ws/public/mojom/window_tree.mojom
@@ -633,9 +633,10 @@ // ScreenProviderObserver for details. GetScreenProviderObserver(associated ScreenProviderObserver& observer); - // Called when the occlusion state changes for a window. See also - // TrackOcclusionState on WindowTree. - OnOcclusionStateChanged(uint64 window_id, OcclusionState occlusion_state); + // Called to send occlusion changes to client. |occlusion_changes| contains + // the changed info, with window id as its key and new occlusion state as its + // data. See also TrackOcclusionState on WindowTree. + OnOcclusionStatesChanged(map<uint64, OcclusionState> occlusion_changes); }; // Mus provides this interface as a way for clients to connect and obtain a
diff --git a/services/ws/test_change_tracker.cc b/services/ws/test_change_tracker.cc index e384eed..8dcbd8af 100644 --- a/services/ws/test_change_tracker.cc +++ b/services/ws/test_change_tracker.cc
@@ -53,6 +53,22 @@ return "UNKNOWN"; } +std::string OcclusionChangesToString( + const base::flat_map<Id, mojom::OcclusionState>& changes) { + std::string ret("{"); + bool first = true; + for (const auto& change : changes) { + if (!first) + ret += ", "; + + ret += std::string("{window_id=") + WindowIdToString(change.first) + + ", state=" + OcclusionStateToString(change.second) + "}"; + first = false; + } + ret += "}"; + return ret; +} + enum class ChangeDescriptionType { ONE, TWO }; std::string ChangeToDescription(const Change& change, @@ -209,11 +225,10 @@ "OnPerformDragDropCompleted id=%d success=%s action=%d", change.change_id, change.bool_value ? "true" : "false", change.drag_drop_action); - case CHANGE_TYPE_ON_OCCLUSION_STATE_CHANGED: + case CHANGE_TYPE_ON_OCCLUSION_STATES_CHANGED: return base::StringPrintf( - "OnOcclusionStateChanged window_id=%s, state=%s", - WindowIdToString(change.window_id).c_str(), - OcclusionStateToString(change.occlusion_state).c_str()); + "OnOcclusionStatesChanged %s", + OcclusionChangesToString(change.occlusion_changes).c_str()); } return std::string(); } @@ -615,13 +630,11 @@ AddChange(change); } -void TestChangeTracker::OnOcclusionStateChanged( - Id window_id, - mojom::OcclusionState occlusion_state) { +void TestChangeTracker::OnOcclusionStatesChanged( + const base::flat_map<Id, mojom::OcclusionState>& occlusion_changes) { Change change; - change.type = CHANGE_TYPE_ON_OCCLUSION_STATE_CHANGED; - change.window_id = window_id; - change.occlusion_state = occlusion_state; + change.type = CHANGE_TYPE_ON_OCCLUSION_STATES_CHANGED; + change.occlusion_changes = occlusion_changes; AddChange(change); }
diff --git a/services/ws/test_change_tracker.h b/services/ws/test_change_tracker.h index bbb1049..1bdf78c 100644 --- a/services/ws/test_change_tracker.h +++ b/services/ws/test_change_tracker.h
@@ -56,7 +56,7 @@ CHANGE_TYPE_DRAG_DROP_DONE, CHANGE_TYPE_TOPMOST_WINDOW_CHANGED, CHANGE_TYPE_ON_PERFORM_DRAG_DROP_COMPLETED, - CHANGE_TYPE_ON_OCCLUSION_STATE_CHANGED, + CHANGE_TYPE_ON_OCCLUSION_STATES_CHANGED, }; // TODO(sky): consider nuking and converting directly to WindowData. @@ -111,7 +111,7 @@ gfx::Point location1; base::flat_map<std::string, std::vector<uint8_t>> drag_data; uint32_t drag_drop_action = 0u; - base::Optional<mojom::OcclusionState> occlusion_state; + base::flat_map<Id, mojom::OcclusionState> occlusion_changes; }; // The ChangeToDescription related functions convert a Change into a string. @@ -236,8 +236,8 @@ bool success, uint32_t action_taken); void RequestClose(Id window_id); - void OnOcclusionStateChanged(Id window_id, - mojom::OcclusionState occlusion_state); + void OnOcclusionStatesChanged( + const base::flat_map<Id, mojom::OcclusionState>& occlusion_changes); private: void AddChange(const Change& change);
diff --git a/services/ws/test_window_tree_client.cc b/services/ws/test_window_tree_client.cc index 0281b30..8d576f0 100644 --- a/services/ws/test_window_tree_client.cc +++ b/services/ws/test_window_tree_client.cc
@@ -287,10 +287,9 @@ screen_provider_observer_binding_.Bind(std::move(observer)); } -void TestWindowTreeClient::OnOcclusionStateChanged( - Id window_id, - mojom::OcclusionState occlusion_state) { - tracker_.OnOcclusionStateChanged(window_id, occlusion_state); +void TestWindowTreeClient::OnOcclusionStatesChanged( + const base::flat_map<Id, mojom::OcclusionState>& occlusion_changes) { + tracker_.OnOcclusionStatesChanged(occlusion_changes); } } // namespace ws
diff --git a/services/ws/test_window_tree_client.h b/services/ws/test_window_tree_client.h index 82d7296..c0bd7ff 100644 --- a/services/ws/test_window_tree_client.h +++ b/services/ws/test_window_tree_client.h
@@ -172,8 +172,8 @@ void RequestClose(Id window_id) override; void GetScreenProviderObserver( mojom::ScreenProviderObserverAssociatedRequest observer) override; - void OnOcclusionStateChanged(Id window_id, - mojom::OcclusionState occlusion_state) override; + void OnOcclusionStatesChanged(const base::flat_map<Id, mojom::OcclusionState>& + occlusion_changes) override; protected: TestChangeTracker tracker_;
diff --git a/services/ws/window_delegate_impl.cc b/services/ws/window_delegate_impl.cc index 416ed566..5f376e80 100644 --- a/services/ws/window_delegate_impl.cc +++ b/services/ws/window_delegate_impl.cc
@@ -7,7 +7,6 @@ #include "services/ws/embedding.h" #include "services/ws/proxy_window.h" #include "services/ws/window_properties.h" -#include "services/ws/window_tree.h" #include "ui/aura/window.h" #include "ui/base/cursor/cursor.h" #include "ui/base/hit_test.h" @@ -87,15 +86,6 @@ void WindowDelegateImpl::OnWindowTargetVisibilityChanged(bool visible) {} -void WindowDelegateImpl::OnWindowOcclusionChanged( - aura::Window::OcclusionState occlusion_state, - const SkRegion&) { - ProxyWindow* const proxy_window = ProxyWindow::GetMayBeNull(window_); - // TODO: Send occluded region. - if (proxy_window) - proxy_window->owning_window_tree()->SendOcclusionState(window_); -} - bool WindowDelegateImpl::HasHitTestMask() const { return false; }
diff --git a/services/ws/window_delegate_impl.h b/services/ws/window_delegate_impl.h index be5951c..fb60a5b 100644 --- a/services/ws/window_delegate_impl.h +++ b/services/ws/window_delegate_impl.h
@@ -43,8 +43,6 @@ void OnWindowDestroying(aura::Window* window) override; void OnWindowDestroyed(aura::Window* window) override; void OnWindowTargetVisibilityChanged(bool visible) override; - void OnWindowOcclusionChanged(aura::Window::OcclusionState occlusion_state, - const SkRegion& occluded_region) override; bool HasHitTestMask() const override; void GetHitTestMask(gfx::Path* mask) const override;
diff --git a/services/ws/window_occlusion_change_builder.cc b/services/ws/window_occlusion_change_builder.cc new file mode 100644 index 0000000..703f38ca --- /dev/null +++ b/services/ws/window_occlusion_change_builder.cc
@@ -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. + +#include "services/ws/window_occlusion_change_builder.h" + +#include <map> +#include <set> + +#include "services/ws/proxy_window.h" +#include "services/ws/window_tree.h" + +namespace ws { + +WindowOcclusionChangeBuilder::WindowOcclusionChangeBuilder() + : inner_(aura::WindowOcclusionChangeBuilder::Create()) {} + +WindowOcclusionChangeBuilder::~WindowOcclusionChangeBuilder() { + // Apply occlusion changes. + inner_.reset(); + + // Get remote windows and group them based on owning trees. + std::map<WindowTree*, std::set<aura::Window*>> changes; + while (!windows_.windows().empty()) { + aura::Window* window = windows_.Pop(); + + ProxyWindow* const proxy_window = ProxyWindow::GetMayBeNull(window); + if (!proxy_window || !proxy_window->owning_window_tree()) + continue; + + changes[proxy_window->owning_window_tree()].insert(window); + } + + // Send out changes on a per-tree basis. + for (auto& change : changes) + change.first->SendOcclusionStates(change.second); +} + +void WindowOcclusionChangeBuilder::Add( + aura::Window* window, + aura::Window::OcclusionState occlusion_state, + SkRegion occluded_region) { + windows_.Add(window); + inner_->Add(window, occlusion_state, occluded_region); +} + +} // namespace ws
diff --git a/services/ws/window_occlusion_change_builder.h b/services/ws/window_occlusion_change_builder.h new file mode 100644 index 0000000..b03a2e6 --- /dev/null +++ b/services/ws/window_occlusion_change_builder.h
@@ -0,0 +1,39 @@ +// 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_WS_WINDOW_OCCLUSION_CHANGE_BUILDER_H_ +#define SERVICES_WS_WINDOW_OCCLUSION_CHANGE_BUILDER_H_ + +#include <memory> + +#include "base/macros.h" +#include "ui/aura/window_occlusion_change_builder.h" +#include "ui/aura/window_tracker.h" + +namespace ws { + +// Group and send occlusion change to corresponding WindowTree in batches. +class WindowOcclusionChangeBuilder : public aura::WindowOcclusionChangeBuilder { + public: + WindowOcclusionChangeBuilder(); + ~WindowOcclusionChangeBuilder() override; + + private: + // WindowOcclusionChangeBuilder: + void Add(aura::Window* window, + aura::Window::OcclusionState occlusion_state, + SkRegion occluded_region) override; + + // Inner builder to apply the changes to windows at Window Service side. + std::unique_ptr<aura::WindowOcclusionChangeBuilder> inner_; + + // Tracks live windows that has a change. + aura::WindowTracker windows_; + + DISALLOW_COPY_AND_ASSIGN(WindowOcclusionChangeBuilder); +}; + +} // namespace ws + +#endif // SERVICES_WS_WINDOW_OCCLUSION_CHANGE_BUILDER_H_
diff --git a/services/ws/window_service.cc b/services/ws/window_service.cc index 33f4cef..df7067e 100644 --- a/services/ws/window_service.cc +++ b/services/ws/window_service.cc
@@ -20,6 +20,7 @@ #include "services/ws/remoting_event_injector.h" #include "services/ws/screen_provider.h" #include "services/ws/user_activity_monitor.h" +#include "services/ws/window_occlusion_change_builder.h" #include "services/ws/window_server_test_impl.h" #include "services/ws/window_service_delegate.h" #include "services/ws/window_service_observer.h" @@ -41,6 +42,13 @@ window->GetProperty(aura::client::kClientWindowHasContent); } +// Factory to create ws::WindowOcclusionChangeBuilder that dispatches occlusion +// change per WindowTree in a single mojo call. +std::unique_ptr<aura::WindowOcclusionChangeBuilder> +CreateOcclusionChangeBuilder() { + return std::make_unique<ws::WindowOcclusionChangeBuilder>(); +} + } // namespace WindowService::WindowService( @@ -75,8 +83,14 @@ aura::PropertyConverter::CreateAcceptAnyValueCallback()); // Extends WindowOcclusionTracker to check whether remote window has content. - env_->GetWindowOcclusionTracker()->set_window_has_content_callback( + auto* occlusion_tracker = env_->GetWindowOcclusionTracker(); + DCHECK(occlusion_tracker); + occlusion_tracker->set_window_has_content_callback( base::BindRepeating(&IsOpaqueProxyWindow)); + + // Makes WindowOcclusionTracker to use ws::WindowOcclusionChangeBuilder. + occlusion_tracker->set_occlusion_change_builder_factory( + base::BindRepeating(&CreateOcclusionChangeBuilder)); } WindowService::~WindowService() {
diff --git a/services/ws/window_tree.cc b/services/ws/window_tree.cc index b2e2ece..f949cd7 100644 --- a/services/ws/window_tree.cc +++ b/services/ws/window_tree.cc
@@ -730,12 +730,16 @@ window_tree_client_->OnTopmostWindowChanged(topmost_ids); } -void WindowTree::SendOcclusionState(aura::Window* window) { - DCHECK(IsWindowKnown(window)); +void WindowTree::SendOcclusionStates(const std::set<aura::Window*>& windows) { + base::flat_map<ws::Id, ws::mojom::OcclusionState> occlusion_changes; + for (auto* window : windows) { + DCHECK(IsWindowKnown(window)); - window_tree_client_->OnOcclusionStateChanged( - TransportIdForWindow(window), - aura::WindowOcclusionStateToMojom(window->occlusion_state())); + // TODO(crbug.com/900568): Send occluded region. + occlusion_changes[TransportIdForWindow(window)] = + aura::WindowOcclusionStateToMojom(window->occlusion_state()); + } + window_tree_client_->OnOcclusionStatesChanged(occlusion_changes); } bool WindowTree::NewWindowImpl(
diff --git a/services/ws/window_tree.h b/services/ws/window_tree.h index 5b8d297..0be968e 100644 --- a/services/ws/window_tree.h +++ b/services/ws/window_tree.h
@@ -118,8 +118,8 @@ // windows, as described for OnTopmostWindowChanged() in window_tree.mojom. void SendTopmostWindows(const std::vector<aura::Window*>& topmosts); - // Notifies the client that the window occlusion state has changed. - void SendOcclusionState(aura::Window* window); + // Notifies the client that the occlusion state of |windows| have changed. + void SendOcclusionStates(const std::set<aura::Window*>& windows); WindowService* window_service() { return window_service_; }
diff --git a/services/ws/window_tree_unittest.cc b/services/ws/window_tree_unittest.cc index 1323547..50945952 100644 --- a/services/ws/window_tree_unittest.cc +++ b/services/ws/window_tree_unittest.cc
@@ -19,7 +19,6 @@ #include "services/ws/proxy_window_test_helper.h" #include "services/ws/public/cpp/property_type_converters.h" #include "services/ws/public/mojom/window_manager.mojom.h" -#include "services/ws/window_delegate_impl.h" #include "services/ws/window_service.h" #include "services/ws/window_service_test_setup.h" #include "services/ws/window_tree_test_helper.h" @@ -2160,41 +2159,110 @@ TEST(WindowTreeTest, OcclusionStateChange) { WindowServiceTestSetup setup; - // WindowDelegateImpl deletes itself when the window is deleted. - WindowDelegateImpl* delegate = new WindowDelegateImpl(); - setup.delegate()->set_delegate_for_next_top_level(delegate); + // Create |tracked| and tracks its occlusion state. + aura::Window* tracked = setup.window_tree_test_helper()->NewTopLevelWindow(); + ASSERT_TRUE(tracked); + tracked->SetBounds(gfx::Rect(0, 0, 10, 10)); - // Create |top_level1| and tracks its occlusion state. - aura::Window* top_level1 = - setup.window_tree_test_helper()->NewTopLevelWindow(); - delegate->set_window(top_level1); - ASSERT_TRUE(top_level1); - top_level1->SetBounds(gfx::Rect(0, 0, 10, 10)); + tracked->TrackOcclusionState(); - top_level1->TrackOcclusionState(); - - // Gets HIDDEN state since |top_level1| is created hidden. + // Gets HIDDEN state since |tracked| is created hidden. EXPECT_TRUE(ContainsChange( - *setup.changes(), "OnOcclusionStateChanged window_id=0,1, state=HIDDEN")); + *setup.changes(), + "OnOcclusionStatesChanged {{window_id=0,1, state=HIDDEN}}")); - // Gets VISIBLE state when |top_level1| is shown. - top_level1->Show(); - EXPECT_TRUE( - ContainsChange(*setup.changes(), - "OnOcclusionStateChanged window_id=0,1, state=VISIBLE")); + // Gets VISIBLE state when |tracked| is shown. + tracked->Show(); + EXPECT_TRUE(ContainsChange( + *setup.changes(), + "OnOcclusionStatesChanged {{window_id=0,1, state=VISIBLE}}")); - // Creates |top_level2| and make it occlude |top_level1|. - aura::Window* top_level2 = + // Creates |blocking_window| and make it occlude |tracked|. + aura::Window* blocking_window = setup.window_tree_test_helper()->NewTopLevelWindow(); - ASSERT_TRUE(top_level2); - top_level2->SetProperty(aura::client::kClientWindowHasContent, true); - top_level2->SetBounds(gfx::Rect(0, 0, 15, 15)); - top_level2->Show(); + ASSERT_TRUE(blocking_window); + blocking_window->SetProperty(aura::client::kClientWindowHasContent, true); + blocking_window->SetBounds(gfx::Rect(0, 0, 15, 15)); + blocking_window->Show(); - // Gets OCCLUDED state since |top_level2| covers |top_level1|. + // Gets OCCLUDED state since |blocking_window| covers |tracked|. + EXPECT_TRUE(ContainsChange( + *setup.changes(), + "OnOcclusionStatesChanged {{window_id=0,1, state=OCCLUDED}}")); +} + +TEST(WindowTreeTest, OcclusionStateChangeBatchSameTree) { + WindowServiceTestSetup setup; + + // Create two tracked windows and tracks their occlusion state. + aura::Window* tracked_1 = + setup.window_tree_test_helper()->NewTopLevelWindow(); + ASSERT_TRUE(tracked_1); + tracked_1->SetBounds(gfx::Rect(0, 0, 10, 10)); + tracked_1->TrackOcclusionState(); + tracked_1->Show(); + + aura::Window* tracked_2 = + setup.window_tree_test_helper()->NewTopLevelWindow(); + ASSERT_TRUE(tracked_2); + tracked_2->SetBounds(gfx::Rect(10, 0, 10, 10)); + tracked_2->TrackOcclusionState(); + tracked_2->Show(); + + // Creates |blocking_window| and make it occlude both tracked windows. + aura::Window* blocking_window = + setup.window_tree_test_helper()->NewTopLevelWindow(); + ASSERT_TRUE(blocking_window); + blocking_window->SetProperty(aura::client::kClientWindowHasContent, true); + blocking_window->SetBounds(gfx::Rect(0, 0, 20, 15)); + blocking_window->Show(); + + // Occlusion changes of windows for the same tree are sent together. EXPECT_TRUE( ContainsChange(*setup.changes(), - "OnOcclusionStateChanged window_id=0,1, state=OCCLUDED")); + "OnOcclusionStatesChanged {{window_id=0,1, " + "state=OCCLUDED}, {window_id=0,2, state=OCCLUDED}}")); +} + +TEST(WindowTreeTest, OcclusionStateChangeBatchDifferentTree) { + WindowServiceTestSetup setup; + + // Create |tracked_1| from default tree. + aura::Window* tracked_1 = + setup.window_tree_test_helper()->NewTopLevelWindow(100); + ASSERT_TRUE(tracked_1); + tracked_1->SetBounds(gfx::Rect(0, 0, 10, 10)); + tracked_1->TrackOcclusionState(); + tracked_1->Show(); + + // Create |tracked_2| from a second tree. + TestWindowTreeClient client2; + std::unique_ptr<WindowTree> tree2 = + setup.service()->CreateWindowTree(&client2); + tree2->InitFromFactory(); + WindowTreeTestHelper tree2_test_helper(tree2.get()); + + aura::Window* tracked_2 = tree2_test_helper.NewTopLevelWindow(200); + ASSERT_TRUE(tracked_2); + tracked_2->SetBounds(gfx::Rect(10, 0, 10, 10)); + tracked_2->TrackOcclusionState(); + tracked_2->Show(); + + // Creates |blocking_window| and make it occlude both tracked windows. + aura::Window* blocking_window = + setup.window_tree_test_helper()->NewTopLevelWindow(); + ASSERT_TRUE(blocking_window); + blocking_window->SetProperty(aura::client::kClientWindowHasContent, true); + blocking_window->SetBounds(gfx::Rect(0, 0, 20, 15)); + blocking_window->Show(); + + // Occlusion changes are sent separately for different trees. + EXPECT_TRUE(ContainsChange(*setup.changes(), + "OnOcclusionStatesChanged {{window_id=0,100, " + "state=OCCLUDED}}")); + EXPECT_TRUE(ContainsChange(*client2.tracker()->changes(), + "OnOcclusionStatesChanged {{window_id=0,200, " + "state=OCCLUDED}}")); } TEST(WindowTreeTest, OcclusionTrackingPause) {
diff --git a/storage/browser/blob/README.md b/storage/browser/blob/README.md index 5897407..f74dd19 100644 --- a/storage/browser/blob/README.md +++ b/storage/browser/blob/README.md
@@ -162,6 +162,16 @@ The `BlobReader` class is for reading blobs, and is accessible off of the `BlobDataHandle` at any time. +Updated Recommendations: +- In `blink::` you'll probably have a `blink::BlobDataHandle`, so use +`FileReaderLoader`/`FileReaderLoaderClient` as an abstraction around the mojom +Blob interface. +- Outside of `blink` (in both browser and renderer): you'll probably have a +`blink::mojom::BlobPtr`, so just call `ReadAll`/`ReadRange` on that directly. +- In legacy cases, only in the browser process, only on the IO thread, where +you only have a `storage::BlobDataHandle` use +`CreateReader/storage::BlobReader`. + # Blob Creation & Transportation (Renderer) **This process is outlined with diagrams and illustrations [here](
diff --git a/storage/browser/blob/blob_reader.h b/storage/browser/blob/blob_reader.h index fe003ab..4614fd6d 100644 --- a/storage/browser/blob/blob_reader.h +++ b/storage/browser/blob/blob_reader.h
@@ -46,6 +46,9 @@ // * If a status of Status::NET_ERROR is returned, that means there was an // error and the net_error() variable contains the error code. // Use a BlobDataHandle to create an instance. +// +// For more information on how to read Blobs in your specific situation, see: +// https://chromium.googlesource.com/chromium/src/+/HEAD/storage/browser/blob/README.md#accessing-reading class STORAGE_EXPORT BlobReader { public: class STORAGE_EXPORT FileStreamReaderProvider {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index e2b1b8e7..e16362b 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -3894,7 +3894,7 @@ } ] }, - "test": "chrome_all_tast_tests" + "test": "chrome_kevin_tast_tests" }, { "swarming": { @@ -9883,714 +9883,6 @@ } ] }, - "linux-gtest-hackathon-dbg": { - "gtest_tests": [ - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "accessibility_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "angle_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "app_shell_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "aura_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "base_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "blink_common_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "blink_fuzzer_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "blink_heap_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "blink_platform_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "boringssl_crypto_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "boringssl_ssl_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 10 - }, - "test": "browser_tests" - }, - { - "args": [ - "--enable-features=NetworkService", - "--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.network_browser_tests.filter" - ], - "name": "network_service_browser_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 15 - }, - "test": "browser_tests" - }, - { - "args": [ - "--enable-features=WebUIPolymer2", - "--test-launcher-filter-file=../../testing/buildbot/filters/webui_polymer2_browser_tests.filter" - ], - "name": "webui_polymer2_browser_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 4 - }, - "test": "browser_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cacheinvalidation_unittests" - }, - { - "args": [ - "--gtest_filter=-*UsingRealWebcam*" - ], - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "capture_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cast_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cc_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "chrome_app_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "chromedriver_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "components_browsertests" - }, - { - "args": [ - "--enable-features=NetworkService" - ], - "name": "network_service_components_browsertests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "components_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "components_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "compositor_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_browsertests" - }, - { - "args": [ - "--enable-features=NetworkService", - "--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter" - ], - "name": "network_service_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 2 - }, - "test": "content_browsertests" - }, - { - "args": [ - "--enable-features=TracingPerfettoBackend", - "--gtest_filter=TracingControllerTest.*" - ], - "name": "perfetto_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cronet_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cronet_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "crypto_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "dbus_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "device_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "display_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "events_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "extensions_browsertests" - }, - { - "args": [ - "--enable-features=NetworkService" - ], - "name": "network_service_extensions_browsertests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "extensions_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "extensions_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "filesystem_service_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gcm_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gfx_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gin_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "google_apis_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gpu_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "headless_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "headless_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 3 - }, - "test": "interactive_ui_tests" - }, - { - "args": [ - "--enable-features=NetworkService" - ], - "name": "network_service_interactive_ui_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 3 - }, - "test": "interactive_ui_tests" - }, - { - "args": [ - "--enable-features=WebUIPolymer2", - "--test-launcher-filter-file=../../testing/buildbot/filters/webui_polymer2_interactive_ui_tests.filter" - ], - "name": "webui_polymer2_interactive_ui_tests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "interactive_ui_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ipc_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "jingle_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "latency_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "leveldb_service_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "libjingle_xmpp_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "media_blink_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "media_service_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "media_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "message_center_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "midi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "mojo_core_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "mojo_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "nacl_helper_nonsfi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "nacl_loader_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "native_theme_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "net_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "pdf_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ppapi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "printing_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "remoting_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "sandbox_linux_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "service_manager_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "services_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "shell_dialogs_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "skia_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "snapshot_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "sql_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "storage_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "sync_integration_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "traffic_annotation_auditor_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ui_base_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ui_touch_selection_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "url_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "views_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "viz_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "vr_common_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "vr_pixeltests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "webkit_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "wm_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "wtf_unittests" - } - ], - "isolated_scripts": [ - { - "isolate_name": "content_shell_crash_test", - "name": "content_shell_crash_test", - "swarming": { - "can_use_on_swarming_builders": true - } - }, - { - "isolate_name": "devtools_closure_compile", - "name": "devtools_closure_compile", - "swarming": { - "can_use_on_swarming_builders": true - } - }, - { - "isolate_name": "devtools_eslint", - "name": "devtools_eslint", - "swarming": { - "can_use_on_swarming_builders": true - } - }, - { - "isolate_name": "metrics_python_tests", - "name": "metrics_python_tests", - "swarming": { - "can_use_on_swarming_builders": true - } - }, - { - "args": [ - "--additional-driver-flag", - "--disable-site-isolation-trials", - "--num-retries=3" - ], - "isolate_name": "webkit_layout_tests_exparchive", - "merge": { - "args": [ - "--verbose" - ], - "script": "//third_party/blink/tools/merge_web_test_results.py" - }, - "name": "not_site_per_process_webkit_layout_tests", - "results_handler": "layout tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04" - } - ], - "shards": 10 - } - }, - { - "isolate_name": "telemetry_gpu_unittests", - "name": "telemetry_gpu_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "idempotent": false - } - }, - { - "isolate_name": "telemetry_perf_unittests", - "name": "telemetry_perf_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "hard_timeout": 960, - "idempotent": false, - "shards": 12 - } - }, - { - "args": [ - "--jobs=1", - "--extra-browser-args=--disable-gpu" - ], - "isolate_name": "telemetry_unittests", - "name": "telemetry_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "idempotent": false, - "shards": 4 - } - }, - { - "isolate_name": "views_perftests", - "name": "views_perftests", - "swarming": { - "can_use_on_swarming_builders": true - } - }, - { - "args": [ - "--num-retries=3" - ], - "isolate_name": "webkit_layout_tests_exparchive", - "merge": { - "args": [ - "--verbose" - ], - "script": "//third_party/blink/tools/merge_web_test_results.py" - }, - "name": "webkit_layout_tests", - "results_handler": "layout tests", - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 12 - } - }, - { - "isolate_name": "webkit_python_tests", - "name": "webkit_python_tests", - "swarming": { - "can_use_on_swarming_builders": true - } - } - ] - }, "linux-tcmalloc-rel": { "gtest_tests": [ {
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 2603d70..dc32b28 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -5272,25 +5272,6 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:6613", - "os": "Ubuntu", - "pool": "Chrome-GPU" - } - ], - "expiration": 21600, - "shards": 4 - }, - "test": "dawn_end2end_tests" - }, - { - "args": [ - "--use-gpu-in-tests", "--use-cmd-decoder=validating" ], "swarming": {
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json index 74d681a6..fb361be 100644 --- a/testing/buildbot/chromium.win.json +++ b/testing/buildbot/chromium.win.json
@@ -738,6 +738,18 @@ } }, { + "isolate_name": "mini_installer_tests", + "name": "mini_installer_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "integrity": "high" + } + ] + } + }, + { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", "swarming": { @@ -4107,6 +4119,18 @@ } }, { + "isolate_name": "mini_installer_tests", + "name": "mini_installer_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "integrity": "high" + } + ] + } + }, + { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", "swarming": {
diff --git a/testing/buildbot/filters/mojo.fyi.chromeos.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.chromeos.network_browser_tests.filter index dd476302..e04919fc 100644 --- a/testing/buildbot/filters/mojo.fyi.chromeos.network_browser_tests.filter +++ b/testing/buildbot/filters/mojo.fyi.chromeos.network_browser_tests.filter
@@ -19,10 +19,6 @@ # Flaky with error: `picture_in_picture_window_controller_impl.cc(167)] Check failed: media_player_id_.has_value()`. -PictureInPictureWindowControllerBrowserTest.TabIconUpdated -# https://crbug.com/914406 --ChromeOsMirrorAccountConsistencyTest.TestMirrorRequestChromeOsNotChildAccount --ChromeOsMirrorAccountConsistencyTest.TestMirrorRequestChromeOsChildAccount - # NOTE: if adding an exclusion for an existing failure (e.g. additional test for # feature X that is already not working), please add it beside the existing # failures. Otherwise please reach out to network-service-dev@.
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 35512c40..c9ba17b6 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -514,6 +514,13 @@ "label": "//chrome/android:chrome_junit_tests", "type": "junit_test", }, + "chrome_kevin_tast_tests": { + "args": [ + "--vm-logs-dir=${ISOLATED_OUTDIR}", + ], + "label": "//chromeos:chrome_kevin_tast_tests", + "type": "raw", + }, "chrome_login_tast_tests": { "args": [ "--vm-logs-dir=${ISOLATED_OUTDIR}",
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 4b175a2..957da86 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -487,6 +487,12 @@ 'linux-win_cross-rel', # https://crbug.com/762167 ], }, + 'dawn_end2end_tests': { + 'remove_from': [ + # chromium.gpu.fyi + 'Linux FYI Release (AMD R7 240)', # https://crbug.com/915430 + ], + }, 'extensions_browsertests': { 'modifications': { 'Win10 Tests x64 (dbg)': {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index fdababe..eb7b9a9 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -463,7 +463,7 @@ 'chromeos_device_kevin_tests': { 'base_unittests': {}, - 'chrome_all_tast_tests': {}, + 'chrome_kevin_tast_tests': {}, 'cros_vm_sanity_test': {}, }, @@ -4453,6 +4453,14 @@ 'win_specific_chromium_gtests', ], + 'chromium_win_rel_isolated_scripts': [ + 'chromedriver_py_tests_isolated_scripts', + 'components_perftests_isolated_scripts', + 'desktop_chromium_isolated_scripts', + 'telemetry_perf_unittests_isolated_scripts', + 'win_specific_isolated_scripts', + ], + # BEGIN composition test suites used by the GPU bots 'gpu_angle_deqp_android_gtests': [
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 194c7c98..8f51f6a1 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -1531,12 +1531,6 @@ 'isolated_scripts': 'chromium_code_coverage_isolated_scripts_and_fuzzers', } }, - 'linux-gtest-hackathon-dbg': { - 'test_suites': { - 'gtest_tests': 'chromium_linux_gtests', - 'isolated_scripts': 'chromium_linux_dbg_isolated_scripts', - } - }, 'linux-tcmalloc-rel': { 'test_suites': { 'gtest_tests': 'chromium_linux_gtests', @@ -3594,7 +3588,7 @@ 'Win 7 Tests x64 (1)': { 'test_suites': { 'gtest_tests': 'chromium_win_gtests', - 'isolated_scripts': 'chromium_rel_isolated_scripts', + 'isolated_scripts': 'chromium_win_rel_isolated_scripts', }, }, 'Win Builder': { @@ -3637,7 +3631,7 @@ 'Win7 Tests (1)': { 'test_suites': { 'gtest_tests': 'chromium_win_gtests', - 'isolated_scripts': 'chromium_rel_isolated_scripts', + 'isolated_scripts': 'chromium_win_rel_isolated_scripts', 'scripts': 'chromium_scripts', }, },
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 80a78ca..26d273b3 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2483,6 +2483,25 @@ ] } ], + "LevelDBPerformRewrite": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LevelDBPerformRewrite" + ] + } + ] + } + ], "LocalScreenCasting": [ { "platforms": [ @@ -3854,25 +3873,6 @@ ] } ], - "RemoveNavigationHistory": [ - { - "platforms": [ - "android", - "chromeos", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "RemoveNavigationHistory" - ] - } - ] - } - ], "RendererSchedulerWakeUpThrottling": [ { "platforms": [ @@ -4566,6 +4566,36 @@ ] } ], + "SyncPseudoUss'": [ + { + "platforms": [ + "android", + "chromeos", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SyncPseudoUSSAppList", + "SyncPseudoUSSApps", + "SyncPseudoUSSDictionary", + "SyncPseudoUSSExtensions", + "SyncPseudoUSSFavicons", + "SyncPseudoUSSHistoryDeleteDirectives", + "SyncPseudoUSSPreferences", + "SyncPseudoUSSPriorityPreferences", + "SyncPseudoUSSSearchEngines", + "SyncPseudoUSSSupervisedUsers", + "SyncPseudoUSSThemes" + ] + } + ] + } + ], "SyncStandaloneTransport": [ { "platforms": [
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index 21a2fe2..f68b4a3 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -161,12 +161,18 @@ public_deps = [ ":mojom_platform", + "//components/payments/mojom", "//mojo/public/mojom/base", + "//services/network/public/mojom", "//skia/public/interfaces", "//url/mojom:url_mojom_gurl", + "//url/mojom:url_mojom_origin", ] - overridden_deps_blink = [ ":mojom_platform" ] + overridden_deps_blink = [ + ":mojom_platform", + "//services/network/public/mojom", + ] component_deps_blink = [ "//third_party/blink/renderer/platform" ] export_class_attribute = "BLINK_COMMON_EXPORT"
diff --git a/third_party/blink/public/mojom/background_fetch/background_fetch.mojom b/third_party/blink/public/mojom/background_fetch/background_fetch.mojom index be6df52..eca2cf3 100644 --- a/third_party/blink/public/mojom/background_fetch/background_fetch.mojom +++ b/third_party/blink/public/mojom/background_fetch/background_fetch.mojom
@@ -112,6 +112,11 @@ // fetch is no longer available. The mojo connection will be closed after // this call. OnRecordsUnavailable(); + + // Notifies the BackgroundFetchRegistration that the |request| has completed. + // |response| points to the completed response, if any. + OnRequestCompleted(FetchAPIRequest request, + FetchAPIResponse? response); }; // Interface for Background Fetch tasks. Lives in the browser process.
diff --git a/third_party/blink/public/mojom/fetch/fetch_api_request.mojom b/third_party/blink/public/mojom/fetch/fetch_api_request.mojom index 5e6fd9f..a7d2f5d3 100644 --- a/third_party/blink/public/mojom/fetch/fetch_api_request.mojom +++ b/third_party/blink/public/mojom/fetch/fetch_api_request.mojom
@@ -151,7 +151,6 @@ mojo_base.mojom.UnguessableToken? fetch_window_id; bool keepalive = false; - string? client_id; bool is_reload = false; bool is_history_navigation = false; };
diff --git a/third_party/blink/public/mojom/service_worker/service_worker.mojom b/third_party/blink/public/mojom/service_worker/service_worker.mojom index 31951624..ea0fa99f 100644 --- a/third_party/blink/public/mojom/service_worker/service_worker.mojom +++ b/third_party/blink/public/mojom/service_worker/service_worker.mojom
@@ -4,9 +4,22 @@ module blink.mojom; +import "mojo/public/mojom/base/string16.mojom"; +import "mojo/public/mojom/base/time.mojom"; +import "services/network/public/mojom/cookie_manager.mojom"; +import "third_party/blink/public/mojom/background_fetch/background_fetch.mojom"; +import "third_party/blink/public/mojom/fetch/fetch_api_response.mojom"; import "third_party/blink/public/mojom/messaging/transferable_message.mojom"; -import "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom"; +import "third_party/blink/public/mojom/notifications/notification.mojom"; +import "third_party/blink/public/mojom/payments/payment_app.mojom"; +import "third_party/blink/public/mojom/service_worker/dispatch_fetch_event_params.mojom"; import "third_party/blink/public/mojom/service_worker/service_worker_client.mojom"; +import "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom"; +import "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom"; +import "third_party/blink/public/mojom/service_worker/service_worker_fetch_response_callback.mojom"; +import "third_party/blink/public/mojom/service_worker/service_worker_object.mojom"; +import "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom"; +import "url/mojom/origin.mojom"; import "url/mojom/url.mojom"; // Host for a running service worker execution context. Implemented in the @@ -91,3 +104,150 @@ // Otherwise, |error| and |error_msg| describe the failure. ClaimClients() => (ServiceWorkerErrorType error, string? error_msg); }; + +struct ExtendableMessageEvent { + TransferableMessage message; + url.mojom.Origin source_origin; + // Exactly one of |source_info_for_client| and + // |source_info_for_service_worker| should be non-null. + ServiceWorkerClientInfo? source_info_for_client; + ServiceWorkerObjectInfo? source_info_for_service_worker; +}; + +// The number of seconds for which a 'push' event should be allowed to run. +// This is not in the spec but for a Chrome-specific timeout. Each +// event dispatched to service workers has a 5 minute timeout in the Chrome +// implementation, but this makes the timeout for push events shorter. +const int32 kPushEventTimeoutSeconds = 90; + +// An interface for talking to a running service worker thread. The browser +// process uses this interface to request the renderer to do things like +// dispatch events to the service worker. This interface is bound on the +// service worker thread and is implemented by ServiceWorkerContextClient. +// +// This is the master interface for the Mojo message pipe between the browser +// process and the service worker thread in the renderer process. Other service +// worker-related interfaces bound on the service worker thread are associated +// with this interface. These include: +// - ServiceWorkerHost for this service worker. +// - ServiceWorkerRegistrationObject(Host) for this service worker's +// self.registration property. +// - ServiceWorkerObjects(Host) for that registration's properties. +// +// A similar (but non-associated) interface is ControllerServiceWorker. That +// interface is used by service worker clients (inside renderer processes) to +// talk directly to their controller service worker, without going through the +// browser. +// +// USAGE TIP: Those DispatchEvent* messages expecting a +// (ServiceWorkerEventStatus, mojo_base.mojom.TimeTicks) callback +// are considered 'simple events'. +// ServiceWorkerVersion::CreateSimpleEventCallback can be used to create the +// callback for these. +interface ServiceWorker { + // The first message sent on this interface. It is used to associate service + // worker-related interfaces together on the service worker thread, as + // ServiceWorker is the first interface available on the + // service worker thread. It establishes the |service_worker_host| connection + // and passes information used to populate + // ServiceWorkerGlobalScope#registration object. JavaScript execution of the + // service worker does not start until this message is received. + InitializeGlobalScope( + associated ServiceWorkerHost service_worker_host, + ServiceWorkerRegistrationObjectInfo registration_info); + + DispatchInstallEvent() + => (ServiceWorkerEventStatus status, bool has_fetch_handler); + DispatchActivateEvent() + => (ServiceWorkerEventStatus status); + + // These methods dispatch to the ServiceWorkerGlobalScope the events listed on + // https://wicg.github.io/background-fetch/#service-worker-global-events. + // The callbacks are called once the event handler has run and waitUntil() + // promise has settled. |developer_id| and |unique_id| are documented in + // content::BackgroundFetchRegistrationId. + DispatchBackgroundFetchAbortEvent( + BackgroundFetchRegistration registration) + => (ServiceWorkerEventStatus status); + DispatchBackgroundFetchClickEvent( + BackgroundFetchRegistration registration) + => (ServiceWorkerEventStatus status); + DispatchBackgroundFetchFailEvent( + BackgroundFetchRegistration registration) + => (ServiceWorkerEventStatus status); + DispatchBackgroundFetchSuccessEvent( + BackgroundFetchRegistration registration) + => (ServiceWorkerEventStatus status); + + // Dispatches the cookie change events in the Async Cookie API specification. + // https://github.com/WICG/cookie-store/ + // The callback is called once the event handler has run and the waitUntil() + // promise has settled. + DispatchCookieChangeEvent( + network.mojom.CanonicalCookie cookie, + network.mojom.CookieChangeCause cause) + => (ServiceWorkerEventStatus status); + + // The Dispatch*FetchEvent() callback is called once the event finishes, + // which means the event handler ran and all outstanding respondWith() and + // waitUntil() promises have settled. |response_callback| is called once the + // promise to respondWith() settles, or when the event handler ran without + // calling respondWith(). + DispatchFetchEvent( + DispatchFetchEventParams params, + ServiceWorkerFetchResponseCallback response_callback) + => (ServiceWorkerEventStatus status); + + DispatchNotificationClickEvent( + string notification_id, + NotificationData notification_data, + int32 action_index, + mojo_base.mojom.String16? reply) + => (ServiceWorkerEventStatus status); + DispatchNotificationCloseEvent( + string notification_id, + NotificationData notification_data) + => (ServiceWorkerEventStatus status); + // The payload of a push message can be valid with content, valid with empty + // content, or null. + DispatchPushEvent(string? payload) + => (ServiceWorkerEventStatus status); + // Arguments are passed to the event handler as parameters of SyncEvent. + // Ref: https://wicg.github.io/BackgroundSync/spec/#sync-event + // S13nServiceWorker: |timeout| is the amount of time to allow this event to + // finish. + // Non-S13nServiceWorker: |timeout| is just ignored. + DispatchSyncEvent(string id, + bool last_chance, + mojo_base.mojom.TimeDelta timeout) + => (ServiceWorkerEventStatus status); + DispatchAbortPaymentEvent( + payments.mojom.PaymentHandlerResponseCallback result_of_abort_payment) + => (ServiceWorkerEventStatus status); + DispatchCanMakePaymentEvent( + payments.mojom.CanMakePaymentEventData event_data, + payments.mojom.PaymentHandlerResponseCallback result_of_can_make_payment) + => (ServiceWorkerEventStatus status); + DispatchPaymentRequestEvent( + payments.mojom.PaymentRequestEventData request_data, + payments.mojom.PaymentHandlerResponseCallback response_callback) + => (ServiceWorkerEventStatus status); + DispatchExtendableMessageEvent(ExtendableMessageEvent event) + => (ServiceWorkerEventStatus status); + + // TODO(crbug.com/869714): Remove this code for long living service workers + // when Android Messages no longer requires it. + DispatchExtendableMessageEventWithCustomTimeout(ExtendableMessageEvent event, + mojo_base.mojom.TimeDelta timeout) + => (ServiceWorkerEventStatus status); + + // Pings the service worker to check if it is responsive. If the callback is + // not called within a certain period of time, the browser will terminate the + // worker. + Ping() => (); + + // S13nServiceWorker: + // Lets the idle timer request termination immediately after all inflight + // events are handled without delay. + SetIdleTimerDelayToZero(); +};
diff --git a/third_party/blink/public/platform/modules/badging/badging.mojom b/third_party/blink/public/platform/modules/badging/badging.mojom index 45ce81c..c230f14 100644 --- a/third_party/blink/public/platform/modules/badging/badging.mojom +++ b/third_party/blink/public/platform/modules/badging/badging.mojom
@@ -6,14 +6,15 @@ // Interface for handling badge messages from frames and subframes. interface BadgeService { - // Sets a badge for the PWA corresponding to the context sending the request - // if such a PWA exists. - // TODO(estevenson): Pass the badge contents from the API. Chrome OS will be - // the first client and will not show the data anyway so for now this is - // sufficient. - SetBadge(); + // Sets the badge for the PWA corresponding to this request to be a + // non-zero, positive integer. + SetInteger(uint64 content); - // Clear badge (if it exists) for the PWA corresponding to the context sending - // the request if such a PWA exists. + // Sets the badge for the PWA corresponding to this request to be a + // flag marker. + SetFlag(); + + // Clears the badge (if it exists) for the PWA corresponding to + // this request. ClearBadge(); };
diff --git a/third_party/blink/public/platform/modules/bluetooth/web_bluetooth.mojom b/third_party/blink/public/platform/modules/bluetooth/web_bluetooth.mojom index cbcd8ef..c27750a 100644 --- a/third_party/blink/public/platform/modules/bluetooth/web_bluetooth.mojom +++ b/third_party/blink/public/platform/modules/bluetooth/web_bluetooth.mojom
@@ -140,6 +140,19 @@ uint32 properties; }; +struct WebBluetoothScanResult { + WebBluetoothDevice device; + string? name; + array<bluetooth.mojom.UUID> uuids; + uint16 appearance; + + // TODO(dougt): Make tx_power and rssi optional. + uint8 tx_power; + uint8 rssi; + map<uint16, array<uint8>> manufacturer_data; + map<string, array<uint8>> service_data; +}; + struct WebBluetoothRemoteGATTDescriptor { string instance_id; // See Instance ID Note above. bluetooth.mojom.UUID uuid; @@ -250,6 +263,10 @@ RemoteDescriptorWriteValue( string descriptor_instance_id, array<uint8> value) => (WebBluetoothResult result); + + // Starts scanning for low energy devices. + RequestScanningStart(associated WebBluetoothScanClient client) => ( + WebBluetoothResult result); }; // Classes that implement this interface will be notified of device events. @@ -264,3 +281,10 @@ // Called when we receive a notification for the characteristic. RemoteCharacteristicValueChanged(array<uint8> value); }; + +// Classes that implement this interface will be notified of scan +// events. +interface WebBluetoothScanClient { + // Called when we receive a notification for the characteristic. + ScanEvent(WebBluetoothScanResult result); +};
diff --git a/third_party/blink/public/platform/web_feature.mojom b/third_party/blink/public/platform/web_feature.mojom index 5924d1d6..42e3179 100644 --- a/third_party/blink/public/platform/web_feature.mojom +++ b/third_party/blink/public/platform/web_feature.mojom
@@ -2102,6 +2102,62 @@ kNavigatorPlatform = 2661, kNavigatorPlugins = 2662, kNavigatorUserAgent = 2663, + kWebBluetoothRequestScan = 2664, + kV8SVGGeometryElement_IsPointInFill_Method = 2665, + kV8SVGGeometryElement_IsPointInStroke_Method = 2666, + kV8SVGGeometryElement_GetTotalLength_Method = 2667, + kV8SVGGeometryElement_GetPointAtLength_Method = 2668, + kOffscreenCanvasTransferToImageBitmap = 2669, + kOffscreenCanvasIsPointInPath = 2670, + kOffscreenCanvasIsPointInStroke = 2671, + kOffscreenCanvasMeasureText = 2672, + kOffscreenCanvasGetImageData = 2673, + kV8SVGTextContentElement_GetComputedTextLength_Method = 2674, + kV8SVGTextContentElement_GetEndPositionOfChar_Method = 2675, + kV8SVGTextContentElement_GetExtentOfChar_Method = 2676, + kV8SVGTextContentElement_GetStartPositionOfChar_Method = 2677, + kV8SVGTextContentElement_GetSubStringLength_Method = 2678, + kV8BatteryManager_ChargingTime_AttributeGetter = 2679, + kV8BatteryManager_Charging_AttributeGetter = 2680, + kV8BatteryManager_DischargingTime_AttributeGetter = 2681, + kV8BatteryManager_Level_AttributeGetter = 2682, + kV8PaintRenderingContext2D_IsPointInPath_Method = 2683, + kV8PaintRenderingContext2D_IsPointInStroke_Method = 2684, + kV8PaymentRequest_CanMakePayment_Method = 2685, + kV8AnalyserNode_GetByteFrequencyData_Method = 2686, + kV8AnalyserNode_GetByteTimeDomainData_Method = 2687, + kV8AnalyserNode_GetFloatFrequencyData_Method = 2688, + kV8AnalyserNode_GetFloatTimeDomainData_Method = 2689, + kV8AudioBuffer_CopyFromChannel_Method = 2690, + kV8AudioBuffer_GetChannelData_Method = 2691, + kWebGLDebugRendererInfo = 2692, + kV8WebGL2ComputeRenderingContext_GetExtension_Method = 2693, + kV8WebGL2ComputeRenderingContext_GetSupportedExtensions_Method = 2694, + kV8WebGL2RenderingContext_GetExtension_Method = 2695, + kV8WebGL2RenderingContext_GetSupportedExtensions_Method = 2696, + kV8WebGLRenderingContext_GetExtension_Method = 2697, + kV8WebGLRenderingContext_GetSupportedExtensions_Method = 2698, + kV8Screen_AvailHeight_AttributeGetter = 2699, + kV8Screen_AvailWidth_AttributeGetter = 2700, + kV8Screen_ColorDepth_AttributeGetter = 2701, + kV8Screen_Height_AttributeGetter = 2702, + kV8Screen_PixelDepth_AttributeGetter = 2703, + kV8Screen_Width_AttributeGetter = 2704, + kWindowInnerWidth = 2705, + kWindowInnerHeight = 2706, + kV8Window_MatchMedia_Method = 2707, + kWindowScrollX = 2708, + kWindowScrollY = 2709, + kWindowPageXOffset = 2710, + kWindowPageYOffset = 2711, + kWindowScreenX = 2712, + kWindowScreenY = 2713, + kWindowOuterHeight = 2714, + kWindowOuterWidth = 2715, + kWindowDevicePixelRatio = 2716, + kCanvasCaptureStream = 2717, + kV8HTMLMediaElement_CanPlayType_Method = 2718, + kHistoryLength = 2719, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/platform/web_graphics_context_3d_provider.h b/third_party/blink/public/platform/web_graphics_context_3d_provider.h index 14b20a3..e60c111 100644 --- a/third_party/blink/public/platform/web_graphics_context_3d_provider.h +++ b/third_party/blink/public/platform/web_graphics_context_3d_provider.h
@@ -44,7 +44,6 @@ namespace gpu { struct Capabilities; struct GpuFeatureInfo; -class SharedImageInterface; namespace gles2 { class GLES2Interface; @@ -83,7 +82,6 @@ virtual cc::ImageDecodeCache* ImageDecodeCache( SkColorType color_type, sk_sp<SkColorSpace> color_space) = 0; - virtual gpu::SharedImageInterface* SharedImageInterface() = 0; }; } // namespace blink
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index b5732529..40ab6bc 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -173,6 +173,7 @@ BLINK_PLATFORM_EXPORT static void EnableWebAuth(bool); BLINK_PLATFORM_EXPORT static void EnableWebAuthGetTransports(bool); BLINK_PLATFORM_EXPORT static void EnableWebBluetooth(bool); + BLINK_PLATFORM_EXPORT static void EnableWebBluetoothScanning(bool); BLINK_PLATFORM_EXPORT static void EnableWebGL2ComputeContext(bool); BLINK_PLATFORM_EXPORT static void EnableWebGLDraftExtensions(bool); BLINK_PLATFORM_EXPORT static void EnableWebGLImageChromium(bool);
diff --git a/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h b/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h index da9863c7..732f423 100644 --- a/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h +++ b/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h
@@ -270,6 +270,16 @@ CreateServiceWorkerFetchContext(WebServiceWorkerNetworkProvider*) { return nullptr; } + + // Called when a task is going to be scheduled on the service worker. + // The service worker shouldn't request to be terminated until the task is + // finished. Returns an id for the task. The caller must call DidEndTask() + // with the returned id to notify that the task is finished. + virtual int WillStartTask() { return -1; } + + // Called when a task is finished. |task_id| must be a return value of + // WillStartTask(). + virtual void DidEndTask(int task_id) {} }; } // namespace blink
diff --git a/third_party/blink/public/web/web_document_loader.h b/third_party/blink/public/web/web_document_loader.h index 60cf2b9..9a380bd 100644 --- a/third_party/blink/public/web/web_document_loader.h +++ b/third_party/blink/public/web/web_document_loader.h
@@ -62,8 +62,15 @@ static bool WillLoadUrlAsEmpty(const WebURL&); - // Returns the original request that resulted in this datasource. - virtual const WebURLRequest& OriginalRequest() const = 0; + // Returns the url of original request which initited this load. + virtual WebURL OriginalUrl() const = 0; + + // Returns the http referrer of original request which initited this load. + virtual WebString OriginalReferrer() const = 0; + + // Returns the url corresponding to this load. It may also be a url + // specified by a redirect that was followed. + virtual WebURL GetUrl() const = 0; // Returns the request corresponding to this datasource. It may // include additional request headers added by WebKit that were not
diff --git a/third_party/blink/renderer/bindings/core/v8/native_value_traits.h b/third_party/blink/renderer/bindings/core/v8/native_value_traits.h index a29ab59..66ae327 100644 --- a/third_party/blink/renderer/bindings/core/v8/native_value_traits.h +++ b/third_party/blink/renderer/bindings/core/v8/native_value_traits.h
@@ -56,11 +56,6 @@ // return toInt32(isolate, value, exceptionState, NormalConversion); // } // } -// -// Note that there exist some specializations (particularly in V8Binding.h) for -// which T actually represents the final C++ type that a JavaScript value -// should be converted to. Introducing new specializations of this kind is -// discouraged. template <typename T, typename SFINAEHelper = void> struct NativeValueTraits;
diff --git a/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h b/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h index ca71a4f0..7b28cf7 100644 --- a/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h +++ b/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h
@@ -28,11 +28,6 @@ }; // Integers -// -// All integer specializations offer a second nativeValue() besides the default -// one: it takes an IntegerConversionConfiguration argument to let callers -// specify how the integers should be converted. The default nativeValue() -// overload will always use NormalConversion. template <> struct CORE_EXPORT NativeValueTraits<IDLByte> : public NativeValueTraitsBase<IDLByte> {
diff --git a/third_party/blink/renderer/bindings/core/v8/script_controller.cc b/third_party/blink/renderer/bindings/core/v8/script_controller.cc index 35405dba..be42ffe 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_controller.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
@@ -211,8 +211,10 @@ EnableEval(); } -bool ScriptController::ExecuteScriptIfJavaScriptURL(const KURL& url, - Element* element) { +bool ScriptController::ExecuteScriptIfJavaScriptURL( + const KURL& url, + Element* element, + ContentSecurityPolicyDisposition check_main_world_csp) { if (!url.ProtocolIsJavaScript()) return false; @@ -221,6 +223,7 @@ url.GetString(), DecodeURLMode::kUTF8OrIsomorphic); bool should_bypass_main_world_content_security_policy = + check_main_world_csp == kDoNotCheckContentSecurityPolicy || ContentSecurityPolicy::ShouldBypassMainWorld(GetFrame()->GetDocument()); if (!GetFrame()->GetPage() || (!should_bypass_main_world_content_security_policy &&
diff --git a/third_party/blink/renderer/bindings/core/v8/script_controller.h b/third_party/blink/renderer/bindings/core/v8/script_controller.h index 89af1d7..946948e0 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_controller.h +++ b/third_party/blink/renderer/bindings/core/v8/script_controller.h
@@ -38,6 +38,7 @@ #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/platform/bindings/shared_persistent.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h" #include "third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h" #include "third_party/blink/renderer/platform/wtf/noncopyable.h" #include "third_party/blink/renderer/platform/wtf/text/text_position.h" @@ -120,7 +121,11 @@ SanitizeScriptErrors sanitize_script_errors); // Returns true if argument is a JavaScript URL. - bool ExecuteScriptIfJavaScriptURL(const KURL&, Element*); + bool ExecuteScriptIfJavaScriptURL( + const KURL&, + Element*, + ContentSecurityPolicyDisposition check_main_world_csp = + kCheckContentSecurityPolicy); // Creates a new isolated world for DevTools with the given human readable // |world_name| and returns it id or nullptr on failure.
diff --git a/third_party/blink/renderer/bindings/modules/v8/generated.gni b/third_party/blink/renderer/bindings/modules/v8/generated.gni index 4bee75f..4df4bd2 100644 --- a/third_party/blink/renderer/bindings/modules/v8/generated.gni +++ b/third_party/blink/renderer/bindings/modules/v8/generated.gni
@@ -78,8 +78,6 @@ "$bindings_modules_v8_output_dir/string_or_unsigned_long.h", "$bindings_modules_v8_output_dir/unsigned_long_or_unsigned_long_sequence.cc", "$bindings_modules_v8_output_dir/unsigned_long_or_unsigned_long_sequence.h", - "$bindings_modules_v8_output_dir/usv_string_or_long.cc", - "$bindings_modules_v8_output_dir/usv_string_or_long.h", "$bindings_modules_v8_output_dir/webgl_rendering_context_or_webgl2_rendering_context.cc", "$bindings_modules_v8_output_dir/webgl_rendering_context_or_webgl2_rendering_context.h", ]
diff --git a/third_party/blink/renderer/build/scripts/core/css/templates/cssom_keywords.cc.tmpl b/third_party/blink/renderer/build/scripts/core/css/templates/cssom_keywords.cc.tmpl index 30c88cc..56fe6df 100644 --- a/third_party/blink/renderer/build/scripts/core/css/templates/cssom_keywords.cc.tmpl +++ b/third_party/blink/renderer/build/scripts/core/css/templates/cssom_keywords.cc.tmpl
@@ -7,6 +7,7 @@ #include "third_party/blink/renderer/core/css/cssom/cssom_keywords.h" +#include "third_party/blink/renderer/core/css/css_property_id_templates.h" #include "third_party/blink/renderer/core/css/cssom/css_keyword_value.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h"
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn index e722610..a127d8ee 100644 --- a/third_party/blink/renderer/core/BUILD.gn +++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1751,7 +1751,6 @@ "css/cssom/css_style_image_value_test.cc", "css/cssom/css_unit_value_test.cc", "css/cssom/css_unparsed_value_test.cc", - "css/cssom/paint_worklet_style_property_map_test.cc", "css/cssom/prepopulated_computed_style_property_map_test.cc", "css/drag_update_test.cc", "css/font_face_cache_test.cc",
diff --git a/third_party/blink/renderer/core/DEPS b/third_party/blink/renderer/core/DEPS index c621de51..3fa0d9eb7 100644 --- a/third_party/blink/renderer/core/DEPS +++ b/third_party/blink/renderer/core/DEPS
@@ -28,7 +28,6 @@ "+cc/paint/display_item_list.h", "+cc/paint/paint_canvas.h", "+cc/paint/paint_flags.h", - "+cc/paint/paint_worklet_input.h", "+gpu/config/gpu_feature_info.h", "-inspector/v8", "+inspector/v8/public",
diff --git a/third_party/blink/renderer/core/css/BUILD.gn b/third_party/blink/renderer/core/css/BUILD.gn index 8b5a6ca7..fe7c36a 100644 --- a/third_party/blink/renderer/core/css/BUILD.gn +++ b/third_party/blink/renderer/core/css/BUILD.gn
@@ -123,6 +123,7 @@ "css_primitive_value_mappings.h", "css_property_equality.cc", "css_property_equality.h", + "css_property_id_templates.h", "css_property_name.cc", "css_property_name.h", "css_property_source_data.cc", @@ -259,10 +260,6 @@ "cssom/element_computed_style_map.h", "cssom/inline_style_property_map.cc", "cssom/inline_style_property_map.h", - "cssom/paint_worklet_input.cc", - "cssom/paint_worklet_input.h", - "cssom/paint_worklet_style_property_map.cc", - "cssom/paint_worklet_style_property_map.h", "cssom/prepopulated_computed_style_property_map.cc", "cssom/prepopulated_computed_style_property_map.h", "cssom/style_property_map.cc",
diff --git a/third_party/blink/renderer/core/css/css_computed_style_declaration.cc b/third_party/blink/renderer/core/css/css_computed_style_declaration.cc index 75c1f11..163d8275 100644 --- a/third_party/blink/renderer/core/css/css_computed_style_declaration.cc +++ b/third_party/blink/renderer/core/css/css_computed_style_declaration.cc
@@ -28,6 +28,7 @@ #include "third_party/blink/renderer/core/css/css_identifier_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h" +#include "third_party/blink/renderer/core/css/css_property_id_templates.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/css/css_selector.h" #include "third_party/blink/renderer/core/css/css_variable_data.h"
diff --git a/third_party/blink/renderer/core/css/css_property_id_templates.h b/third_party/blink/renderer/core/css/css_property_id_templates.h new file mode 100644 index 0000000..ac0f2f50b --- /dev/null +++ b/third_party/blink/renderer/core/css/css_property_id_templates.h
@@ -0,0 +1,30 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_PROPERTY_ID_TEMPLATES_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_PROPERTY_ID_TEMPLATES_H_ + +#include "third_party/blink/renderer/core/css/css_property_names.h" +#include "third_party/blink/renderer/platform/wtf/hash_functions.h" +#include "third_party/blink/renderer/platform/wtf/hash_traits.h" + +namespace WTF { +template <> +struct DefaultHash<blink::CSSPropertyID> { + typedef IntHash<unsigned> Hash; +}; +template <> +struct HashTraits<blink::CSSPropertyID> + : GenericHashTraits<blink::CSSPropertyID> { + static const bool kEmptyValueIsZero = true; + static void ConstructDeletedValue(blink::CSSPropertyID& slot, bool) { + slot = static_cast<blink::CSSPropertyID>(blink::numCSSPropertyIDs); + } + static bool IsDeletedValue(blink::CSSPropertyID value) { + return value == blink::numCSSPropertyIDs; + } +}; +} // namespace WTF + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_PROPERTY_ID_TEMPLATES_H_
diff --git a/third_party/blink/renderer/core/css/css_style_declaration.cc b/third_party/blink/renderer/core/css/css_style_declaration.cc index ae8683b..d4c6148 100644 --- a/third_party/blink/renderer/core/css/css_style_declaration.cc +++ b/third_party/blink/renderer/core/css/css_style_declaration.cc
@@ -33,6 +33,7 @@ #include <algorithm> #include "third_party/blink/renderer/core/css/css_primitive_value.h" +#include "third_party/blink/renderer/core/css/css_property_id_templates.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/css/css_style_declaration.h" #include "third_party/blink/renderer/core/css/css_value.h"
diff --git a/third_party/blink/renderer/core/css/cssom/css_unsupported_style_value.h b/third_party/blink/renderer/core/css/cssom/css_unsupported_style_value.h index 3eb73ef..b206419 100644 --- a/third_party/blink/renderer/core/css/cssom/css_unsupported_style_value.h +++ b/third_party/blink/renderer/core/css/cssom/css_unsupported_style_value.h
@@ -28,9 +28,6 @@ static CSSUnsupportedStyleValue* Create(const CSSValue& value) { return MakeGarbageCollected<CSSUnsupportedStyleValue>(value.CssText()); } - static CSSUnsupportedStyleValue* Create(const String& css_text) { - return MakeGarbageCollected<CSSUnsupportedStyleValue>(css_text); - } static CSSUnsupportedStyleValue* Create(const CSSPropertyName& name, const String& css_text) { return MakeGarbageCollected<CSSUnsupportedStyleValue>(name, css_text);
diff --git a/third_party/blink/renderer/core/css/cssom/paint_worklet_input.cc b/third_party/blink/renderer/core/css/cssom/paint_worklet_input.cc deleted file mode 100644 index 6b3386f..0000000 --- a/third_party/blink/renderer/core/css/cssom/paint_worklet_input.cc +++ /dev/null
@@ -1,25 +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 "third_party/blink/renderer/core/css/cssom/paint_worklet_input.h" - -namespace blink { - -PaintWorkletInput::PaintWorkletInput( - const std::string& name, - const FloatSize& container_size, - float effective_zoom, - const Document& document, - const ComputedStyle& style, - Node* styled_node, - const Vector<CSSPropertyID>& native_properties, - const Vector<AtomicString>& custom_properties) - : name_(name), - container_size_(container_size), - effective_zoom_(effective_zoom) { - style_map_ = MakeGarbageCollected<PaintWorkletStylePropertyMap>( - document, style, styled_node, native_properties, custom_properties); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/css/cssom/paint_worklet_input.h b/third_party/blink/renderer/core/css/cssom/paint_worklet_input.h deleted file mode 100644 index 1eb8452..0000000 --- a/third_party/blink/renderer/core/css/cssom/paint_worklet_input.h +++ /dev/null
@@ -1,51 +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 THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSSOM_PAINT_WORKLET_INPUT_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSSOM_PAINT_WORKLET_INPUT_H_ - -#include <memory> -#include "cc/paint/paint_worklet_input.h" -#include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.h" -#include "third_party/blink/renderer/platform/geometry/float_size.h" -#include "third_party/blink/renderer/platform/heap/persistent.h" - -namespace blink { - -class CORE_EXPORT PaintWorkletInput : public cc::PaintWorkletInput { - public: - PaintWorkletInput(const std::string& name, - const FloatSize& container_size, - float effective_zoom, - const Document&, - const ComputedStyle&, - Node* styled_node, - const Vector<CSSPropertyID>& native_properties, - const Vector<AtomicString>& custom_properties); - - ~PaintWorkletInput() override = default; - - // PaintWorkletInput implementation - gfx::SizeF GetSize() const override { - return gfx::SizeF(container_size_.Width(), container_size_.Height()); - } - - const std::string& Name() const { return name_; } - const FloatSize& ContainerSize() const { return container_size_; } - float EffectiveZoom() const { return effective_zoom_; } - PaintWorkletStylePropertyMap* StyleMap() { return style_map_.Get(); } - - private: - // TODO(xidachen): these members should be const as they are immutable once - // created. - std::string name_; - FloatSize container_size_; - float effective_zoom_; - CrossThreadPersistent<PaintWorkletStylePropertyMap> style_map_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSSOM_PAINT_WORKLET_INPUT_H_
diff --git a/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.cc b/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.cc deleted file mode 100644 index 72fd28f..0000000 --- a/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.cc +++ /dev/null
@@ -1,178 +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 "third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.h" - -#include "third_party/blink/renderer/core/css/css_custom_property_declaration.h" -#include "third_party/blink/renderer/core/css/css_variable_data.h" -#include "third_party/blink/renderer/core/css/cssom/computed_style_property_map.h" -#include "third_party/blink/renderer/core/css/cssom/css_unparsed_value.h" -#include "third_party/blink/renderer/core/css/cssom/css_unsupported_style_value.h" -#include "third_party/blink/renderer/core/css/properties/css_property_ref.h" -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/style/computed_style.h" - -namespace blink { - -namespace { - -class PaintWorkletStylePropertyMapIterationSource final - : public PairIterable<String, CSSStyleValueVector>::IterationSource { - public: - explicit PaintWorkletStylePropertyMapIterationSource( - HeapVector<PaintWorkletStylePropertyMap::StylePropertyMapEntry> values) - : index_(0), values_(values) {} - - bool Next(ScriptState*, - String& key, - CSSStyleValueVector& value, - ExceptionState&) override { - if (index_ >= values_.size()) - return false; - - const PaintWorkletStylePropertyMap::StylePropertyMapEntry& pair = - values_.at(index_++); - key = pair.first; - value = pair.second; - return true; - } - - void Trace(blink::Visitor* visitor) override { - visitor->Trace(values_); - PairIterable<String, CSSStyleValueVector>::IterationSource::Trace(visitor); - } - - private: - wtf_size_t index_; - const HeapVector<PaintWorkletStylePropertyMap::StylePropertyMapEntry> values_; -}; - -} // namespace - -PaintWorkletStylePropertyMap::PaintWorkletStylePropertyMap( - const Document& document, - const ComputedStyle& style, - Node* styled_node, - const Vector<CSSPropertyID>& native_properties, - const Vector<AtomicString>& custom_properties) - : StylePropertyMapReadOnly() { - DCHECK(IsMainThread()); - native_values_.ReserveCapacityForSize(native_properties.size()); - custom_values_.ReserveCapacityForSize(custom_properties.size()); - BuildNativeValues(style, styled_node, native_properties); - BuildCustomValues(document, style, styled_node, custom_properties); -} - -void PaintWorkletStylePropertyMap::BuildNativeValues( - const ComputedStyle& style, - Node* styled_node, - const Vector<CSSPropertyID>& native_properties) { - DCHECK(IsMainThread()); - for (const auto& property_id : native_properties) { - // Silently drop shorthand properties. - DCHECK_NE(property_id, CSSPropertyInvalid); - DCHECK_NE(property_id, CSSPropertyVariable); - if (CSSProperty::Get(property_id).IsShorthand()) - continue; - const CSSValue* css_value = - CSSProperty::Get(property_id) - .CSSValueFromComputedStyle(style, /* layout_object */ nullptr, - styled_node, - /* allow_visited_style */ false); - // Ensure that the String can be safely passed cross threads. - String value = css_value->CssText(); - if (!value.IsSafeToSendToAnotherThread()) - value = value.IsolatedCopy(); - native_values_.Set(property_id, value); - } -} - -void PaintWorkletStylePropertyMap::BuildCustomValues( - const Document& document, - const ComputedStyle& style, - Node* styled_node, - const Vector<AtomicString>& custom_properties) { - DCHECK(IsMainThread()); - for (const auto& property_name : custom_properties) { - CSSPropertyRef ref(property_name, document); - const CSSValue* css_value = ref.GetProperty().CSSValueFromComputedStyle( - style, /* layout_object */ nullptr, styled_node, - /* allow_visited_style */ false); - if (!css_value) - css_value = CSSUnparsedValue::Create()->ToCSSValue(); - // Ensure that the String can be safely passed cross threads. - String key = property_name.GetString(); - if (!key.IsSafeToSendToAnotherThread()) - key = key.IsolatedCopy(); - String value = css_value->CssText(); - if (!value.IsSafeToSendToAnotherThread()) - value = value.IsolatedCopy(); - custom_values_.Set(key, value); - } -} - -CSSStyleValue* PaintWorkletStylePropertyMap::get( - const ExecutionContext* execution_context, - const String& property_name, - ExceptionState& exception_state) { - CSSStyleValueVector all_values = - getAll(execution_context, property_name, exception_state); - return all_values.IsEmpty() ? nullptr : all_values[0]; -} - -CSSStyleValueVector PaintWorkletStylePropertyMap::getAll( - const ExecutionContext* execution_context, - const String& property_name, - ExceptionState& exception_state) { - CSSPropertyID property_id = cssPropertyID(property_name); - if (property_id == CSSPropertyInvalid) { - exception_state.ThrowTypeError("Invalid propertyName: " + property_name); - return CSSStyleValueVector(); - } - - DCHECK(isValidCSSPropertyID(property_id)); - - CSSStyleValueVector values; - // Custom property - if (property_id == CSSPropertyVariable) { - auto value = custom_values_.find(property_name); - if (value == custom_values_.end()) - return CSSStyleValueVector(); - values.push_back(CSSUnsupportedStyleValue::Create(value->value)); - } else { - auto value = native_values_.find(property_id); - if (value == native_values_.end()) - return CSSStyleValueVector(); - values.push_back(CSSUnsupportedStyleValue::Create(value->value)); - } - return values; -} - -bool PaintWorkletStylePropertyMap::has( - const ExecutionContext* execution_context, - const String& property_name, - ExceptionState& exception_state) { - return !getAll(execution_context, property_name, exception_state).IsEmpty(); -} - -unsigned PaintWorkletStylePropertyMap::size() { - return native_values_.size() + custom_values_.size(); -} - -PaintWorkletStylePropertyMap::IterationSource* -PaintWorkletStylePropertyMap::StartIteration(ScriptState* script_state, - ExceptionState& exception_state) { - // TODO(xidachen): implement this function. Note that the output should be - // sorted. - NOTREACHED(); - HeapVector<PaintWorkletStylePropertyMap::StylePropertyMapEntry> result; - return MakeGarbageCollected<PaintWorkletStylePropertyMapIterationSource>( - result); -} - -void PaintWorkletStylePropertyMap::Trace(blink::Visitor* visitor) { - StylePropertyMapReadOnly::Trace(visitor); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.h b/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.h deleted file mode 100644 index e5b8463..0000000 --- a/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.h +++ /dev/null
@@ -1,78 +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 THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSSOM_PAINT_WORKLET_STYLE_PROPERTY_MAP_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSSOM_PAINT_WORKLET_STYLE_PROPERTY_MAP_H_ - -#include "base/macros.h" -#include "third_party/blink/renderer/core/css/cssom/style_property_map_read_only.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" - -namespace blink { - -// This class is designed for CSS Paint such that it can be safely passed cross -// threads. -// -// Here is a typical usage. -// At CSSPaintValue::GetImage which is on the main thread, build an instance -// of Blink::PaintWorkletInput which calls the constructor of this class. The -// ownership of this style map belongs to the Blink::PaintWorkletInput, which -// will eventually be passed to the worklet thread and used in the JS callback. -class CORE_EXPORT PaintWorkletStylePropertyMap - : public StylePropertyMapReadOnly { - public: - using StylePropertyMapEntry = std::pair<String, CSSStyleValueVector>; - // This constructor should be called on main-thread only. - PaintWorkletStylePropertyMap(const Document&, - const ComputedStyle&, - Node* styled_node, - const Vector<CSSPropertyID>& native_properties, - const Vector<AtomicString>& custom_properties); - - CSSStyleValue* get(const ExecutionContext*, - const String& property_name, - ExceptionState&) override; - - CSSStyleValueVector getAll(const ExecutionContext*, - const String& property_name, - ExceptionState&) override; - - bool has(const ExecutionContext*, - const String& property_name, - ExceptionState&) override; - - unsigned int size() override; - - void Trace(blink::Visitor*) override; - - const HashMap<CSSPropertyID, String>& NativeValuesForTest() { - return native_values_; - } - const HashMap<String, String>& CustomValuesForTest() { - return custom_values_; - } - - private: - IterationSource* StartIteration(ScriptState*, ExceptionState&) override; - - void BuildNativeValues(const ComputedStyle&, - Node* styled_node, - const Vector<CSSPropertyID>& native_properties); - void BuildCustomValues(const Document&, - const ComputedStyle&, - Node* styled_node, - const Vector<AtomicString>& custom_properties); - - // TODO(xidachen): we could merge the following two hash maps, because the get - // and getAll both take a String as input, and we convert it to CSSPropertyID - // to look up. - HashMap<CSSPropertyID, String> native_values_; - HashMap<String, String> custom_values_; - - DISALLOW_COPY_AND_ASSIGN(PaintWorkletStylePropertyMap); -}; - -} // namespace blink - -#endif
diff --git a/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map_test.cc b/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map_test.cc deleted file mode 100644 index 92d28d1..0000000 --- a/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map_test.cc +++ /dev/null
@@ -1,184 +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 "third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.h" - -#include <memory> -#include "base/single_thread_task_runner.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/core/css/css_computed_style_declaration.h" -#include "third_party/blink/renderer/core/css/cssom/paint_worklet_input.h" -#include "third_party/blink/renderer/core/dom/element.h" -#include "third_party/blink/renderer/core/dom/node_computed_style.h" -#include "third_party/blink/renderer/core/testing/page_test_base.h" -#include "third_party/blink/renderer/platform/cross_thread_functional.h" -#include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" -#include "third_party/blink/renderer/platform/waitable_event.h" -#include "third_party/blink/renderer/platform/web_thread_supporting_gc.h" - -namespace blink { - -class PaintWorkletStylePropertyMapTest : public PageTestBase { - public: - PaintWorkletStylePropertyMapTest() = default; - - void SetUp() override { PageTestBase::SetUp(IntSize()); } - - Node* PageNode() { return GetDocument().documentElement(); } - - static void CheckCustomProperties( - PaintWorkletStylePropertyMap* map, - DummyExceptionStateForTesting& exception_state) { - const CSSStyleValue* foo = map->get(nullptr, "--foo", exception_state); - ASSERT_NE(nullptr, foo); - ASSERT_EQ(CSSStyleValue::kUnknownType, foo->GetType()); - EXPECT_FALSE(exception_state.HadException()); - - EXPECT_EQ(true, map->has(nullptr, "--foo", exception_state)); - EXPECT_FALSE(exception_state.HadException()); - - CSSStyleValueVector fooAll = map->getAll(nullptr, "--foo", exception_state); - EXPECT_EQ(1U, fooAll.size()); - ASSERT_NE(nullptr, fooAll[0]); - ASSERT_EQ(CSSStyleValue::kUnknownType, fooAll[0]->GetType()); - EXPECT_FALSE(exception_state.HadException()); - - EXPECT_EQ(nullptr, map->get(nullptr, "--quix", exception_state)); - EXPECT_FALSE(exception_state.HadException()); - - EXPECT_EQ(false, map->has(nullptr, "--quix", exception_state)); - EXPECT_FALSE(exception_state.HadException()); - - EXPECT_EQ(CSSStyleValueVector(), - map->getAll(nullptr, "--quix", exception_state)); - EXPECT_FALSE(exception_state.HadException()); - } - - static void CheckNativeProperties( - PaintWorkletStylePropertyMap* map, - DummyExceptionStateForTesting& exception_state) { - map->get(nullptr, "color", exception_state); - EXPECT_FALSE(exception_state.HadException()); - - map->has(nullptr, "color", exception_state); - EXPECT_FALSE(exception_state.HadException()); - - map->getAll(nullptr, "color", exception_state); - EXPECT_FALSE(exception_state.HadException()); - - map->get(nullptr, "align-contents", exception_state); - EXPECT_TRUE(exception_state.HadException()); - exception_state.ClearException(); - - map->has(nullptr, "align-contents", exception_state); - EXPECT_TRUE(exception_state.HadException()); - exception_state.ClearException(); - - map->getAll(nullptr, "align-contents", exception_state); - EXPECT_TRUE(exception_state.HadException()); - exception_state.ClearException(); - } - - static void CheckStyleMap(WaitableEvent* waitable_event, - scoped_refptr<PaintWorkletInput> input) { - DCHECK(!IsMainThread()); - - PaintWorkletStylePropertyMap* map = input->StyleMap(); - DCHECK(map); - - HashMap<CSSPropertyID, String> native_values = map->NativeValuesForTest(); - EXPECT_EQ(native_values.size(), 2u); - EXPECT_EQ(native_values.at(CSSPropertyColor), "rgb(0, 255, 0)"); - EXPECT_EQ(native_values.at(CSSPropertyAlignItems), "normal"); - - HashMap<String, String> custom_values = map->CustomValuesForTest(); - EXPECT_EQ(custom_values.size(), 2u); - EXPECT_EQ(custom_values.at("--foo"), "PaintWorklet"); - EXPECT_EQ(custom_values.at("--bar"), ""); - - waitable_event->Signal(); - } -}; - -TEST_F(PaintWorkletStylePropertyMapTest, NativePropertyAccessors) { - Vector<CSSPropertyID> native_properties( - {CSSPropertyColor, CSSPropertyAlignItems, CSSPropertyBackground}); - Vector<AtomicString> empty_custom_properties; - GetDocument().documentElement()->style()->setProperty( - &GetDocument(), "color", "rgb(0, 255, 0)", "", ASSERT_NO_EXCEPTION); - - UpdateAllLifecyclePhasesForTest(); - Node* node = PageNode(); - - PaintWorkletStylePropertyMap* map = - MakeGarbageCollected<PaintWorkletStylePropertyMap>( - GetDocument(), node->ComputedStyleRef(), node, native_properties, - empty_custom_properties); - - HashMap<CSSPropertyID, String> native_values = map->NativeValuesForTest(); - EXPECT_EQ(native_values.size(), 2u); - EXPECT_EQ(native_values.at(CSSPropertyColor), "rgb(0, 255, 0)"); - EXPECT_EQ(native_values.at(CSSPropertyAlignItems), "normal"); - - DummyExceptionStateForTesting exception_state; - CheckNativeProperties(map, exception_state); -} - -TEST_F(PaintWorkletStylePropertyMapTest, CustomPropertyAccessors) { - Vector<CSSPropertyID> empty_native_properties; - Vector<AtomicString> custom_properties({"--foo", "--bar"}); - GetDocument().documentElement()->style()->setProperty( - &GetDocument(), "--foo", "PaintWorklet", "", ASSERT_NO_EXCEPTION); - - UpdateAllLifecyclePhasesForTest(); - Node* node = PageNode(); - - PaintWorkletStylePropertyMap* map = - MakeGarbageCollected<PaintWorkletStylePropertyMap>( - GetDocument(), node->ComputedStyleRef(), node, - empty_native_properties, custom_properties); - - HashMap<String, String> custom_values = map->CustomValuesForTest(); - EXPECT_EQ(custom_values.size(), 2u); - EXPECT_EQ(custom_values.at("--foo"), "PaintWorklet"); - EXPECT_EQ(custom_values.at("--bar"), ""); - - DummyExceptionStateForTesting exception_state; - CheckCustomProperties(map, exception_state); -} - -// This test ensures that Blink::PaintWorkletInput can be safely passed cross -// threads and no information is lost. -TEST_F(PaintWorkletStylePropertyMapTest, PassValuesCrossThreads) { - Vector<CSSPropertyID> native_properties( - {CSSPropertyColor, CSSPropertyAlignItems}); - GetDocument().documentElement()->style()->setProperty( - &GetDocument(), "color", "rgb(0, 255, 0)", "", ASSERT_NO_EXCEPTION); - Vector<AtomicString> custom_properties({"--foo", "--bar"}); - GetDocument().documentElement()->style()->setProperty( - &GetDocument(), "--foo", "PaintWorklet", "", ASSERT_NO_EXCEPTION); - - UpdateAllLifecyclePhasesForTest(); - Node* node = PageNode(); - - scoped_refptr<PaintWorkletInput> input = - base::MakeRefCounted<PaintWorkletInput>( - "test", FloatSize(100, 100), 1.0f, GetDocument(), - node->ComputedStyleRef(), node, native_properties, custom_properties); - DCHECK(input); - - // TODO(xidachen): this isn't enough, find a right thread such that we can do - // CheckNative/CustomProperties on that thread. - std::unique_ptr<WebThreadSupportingGC> thread = WebThreadSupportingGC::Create( - ThreadCreationParams(WebThreadType::kTestThread)); - WaitableEvent waitable_event; - thread->PostTask( - FROM_HERE, CrossThreadBind( - &PaintWorkletStylePropertyMapTest::CheckStyleMap, - CrossThreadUnretained(&waitable_event), std::move(input))); - waitable_event.Wait(); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h b/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h index e93106e..7d346e5f 100644 --- a/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h +++ b/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSSOM_PREPOPULATED_COMPUTED_STYLE_PROPERTY_MAP_H_ #include "base/macros.h" +#include "third_party/blink/renderer/core/css/css_property_id_templates.h" #include "third_party/blink/renderer/core/css/cssom/style_property_map_read_only_main_thread.h" namespace blink {
diff --git a/third_party/blink/renderer/core/css/resolver/element_style_resources.h b/third_party/blink/renderer/core/css/resolver/element_style_resources.h index a3e8f81..f90ebdba 100644 --- a/third_party/blink/renderer/core/css/resolver/element_style_resources.h +++ b/third_party/blink/renderer/core/css/resolver/element_style_resources.h
@@ -25,6 +25,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_ELEMENT_STYLE_RESOURCES_H_ #include "base/macros.h" +#include "third_party/blink/renderer/core/css/css_property_id_templates.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/platform/cross_origin_attribute_value.h" #include "third_party/blink/renderer/platform/graphics/color.h"
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc b/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc index be55e698..ac8385db 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
@@ -14,13 +14,6 @@ namespace blink { -void RunPendingTasks() { - base::RunLoop run_loop; - Thread::Current()->GetTaskRunner()->PostTask(FROM_HERE, - run_loop.QuitWhenIdleClosure()); - run_loop.Run(); -} - class DisplayLockContextTest : public RenderingTest { public: void SetUp() override { @@ -36,6 +29,13 @@ } } + static void RunPendingTasks() { + base::RunLoop run_loop; + Thread::Current()->GetTaskRunner()->PostTask( + FROM_HERE, run_loop.QuitWhenIdleClosure()); + run_loop.Run(); + } + DisplayLockContext::State ContextState(DisplayLockContext* context) const { return context->state_; }
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 20b1baa0..6b3f2274 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -5397,7 +5397,7 @@ const AtomicString& Document::referrer() const { if (Loader()) - return Loader()->GetRequest().HttpReferrer(); + return Loader()->Referrer(); return g_null_atom; } @@ -6964,8 +6964,13 @@ } ScriptedIdleTaskController& Document::EnsureScriptedIdleTaskController() { - if (!scripted_idle_task_controller_) + if (!scripted_idle_task_controller_) { scripted_idle_task_controller_ = ScriptedIdleTaskController::Create(this); + // We need to make sure that we don't start up the idle controller if we + // don't have an attached frame. + if (!frame_ || !frame_->IsAttached()) + scripted_idle_task_controller_->Pause(); + } return *scripted_idle_task_controller_; }
diff --git a/third_party/blink/renderer/core/events/event_type_names.json5 b/third_party/blink/renderer/core/events/event_type_names.json5 index b06d199f..aa9609a 100644 --- a/third_party/blink/renderer/core/events/event_type_names.json5 +++ b/third_party/blink/renderer/core/events/event_type_names.json5
@@ -30,6 +30,7 @@ "addsourcebuffer", "addstream", "addtrack", + "advertisementreceived", "afterprint", "animationend", "animationiteration",
diff --git a/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc b/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc index 9763585..93f5fe78 100644 --- a/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc +++ b/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc
@@ -342,7 +342,6 @@ WebWidget::LifecycleUpdateReason::kTest); web_view->SetPageScaleFactor(2); - web_view->MainFrameImpl()->SetInputEventsScaleForEmulation(1.5); LocalFrameView* view = ToLocalFrame(web_view->GetPage()->MainFrame())->View(); @@ -359,8 +358,8 @@ TransformWebMouseEvent(view, web_mouse_event); FloatPoint position = transformed_event.PositionInRootFrame(); - EXPECT_FLOAT_EQ(30, position.X()); - EXPECT_FLOAT_EQ(30, position.Y()); + EXPECT_FLOAT_EQ(45, position.X()); + EXPECT_FLOAT_EQ(45, position.Y()); EXPECT_EQ(90, transformed_event.PositionInScreen().x); EXPECT_EQ(90, transformed_event.PositionInScreen().y); EXPECT_EQ(60, transformed_event.movement_x); @@ -392,8 +391,8 @@ EXPECT_EQ(events.size(), coalescedevents.size()); FloatPoint position = coalescedevents[0].PositionInRootFrame(); - EXPECT_FLOAT_EQ(30, position.X()); - EXPECT_FLOAT_EQ(30, position.Y()); + EXPECT_FLOAT_EQ(45, position.X()); + EXPECT_FLOAT_EQ(45, position.Y()); EXPECT_EQ(90, coalescedevents[0].PositionInScreen().x); EXPECT_EQ(90, coalescedevents[0].PositionInScreen().y); @@ -401,8 +400,8 @@ EXPECT_EQ(60, coalescedevents[0].movement_y); position = coalescedevents[1].PositionInRootFrame(); - EXPECT_FLOAT_EQ(30, position.X()); - EXPECT_FLOAT_EQ(40, position.Y()); + EXPECT_FLOAT_EQ(45, position.X()); + EXPECT_FLOAT_EQ(60, position.Y()); EXPECT_EQ(90, coalescedevents[1].PositionInScreen().x); EXPECT_EQ(120, coalescedevents[1].PositionInScreen().y); @@ -424,12 +423,12 @@ TransformWebGestureEvent(view, web_gesture_event); FloatPoint position = scaled_gesture_event.PositionInRootFrame(); - EXPECT_FLOAT_EQ(30, position.X()); - EXPECT_FLOAT_EQ(30, position.Y()); + EXPECT_FLOAT_EQ(45, position.X()); + EXPECT_FLOAT_EQ(45, position.Y()); EXPECT_EQ(90, scaled_gesture_event.PositionInScreen().x); EXPECT_EQ(90, scaled_gesture_event.PositionInScreen().y); - EXPECT_EQ(20, scaled_gesture_event.DeltaXInRootFrame()); - EXPECT_EQ(20, scaled_gesture_event.DeltaYInRootFrame()); + EXPECT_EQ(30, scaled_gesture_event.DeltaXInRootFrame()); + EXPECT_EQ(30, scaled_gesture_event.DeltaYInRootFrame()); } { @@ -443,8 +442,8 @@ WebGestureEvent scaled_gesture_event = TransformWebGestureEvent(view, web_gesture_event); IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame()); - EXPECT_EQ(10, area.Width()); - EXPECT_EQ(10, area.Height()); + EXPECT_EQ(15, area.Width()); + EXPECT_EQ(15, area.Height()); } { @@ -458,8 +457,8 @@ WebGestureEvent scaled_gesture_event = TransformWebGestureEvent(view, web_gesture_event); IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame()); - EXPECT_EQ(10, area.Width()); - EXPECT_EQ(10, area.Height()); + EXPECT_EQ(15, area.Width()); + EXPECT_EQ(15, area.Height()); } { @@ -473,8 +472,8 @@ WebGestureEvent scaled_gesture_event = TransformWebGestureEvent(view, web_gesture_event); IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame()); - EXPECT_EQ(10, area.Width()); - EXPECT_EQ(10, area.Height()); + EXPECT_EQ(15, area.Width()); + EXPECT_EQ(15, area.Height()); } { @@ -488,8 +487,8 @@ WebGestureEvent scaled_gesture_event = TransformWebGestureEvent(view, web_gesture_event); IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame()); - EXPECT_EQ(10, area.Width()); - EXPECT_EQ(10, area.Height()); + EXPECT_EQ(15, area.Width()); + EXPECT_EQ(15, area.Height()); } { @@ -503,8 +502,8 @@ WebGestureEvent scaled_gesture_event = TransformWebGestureEvent(view, web_gesture_event); IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame()); - EXPECT_EQ(10, area.Width()); - EXPECT_EQ(10, area.Height()); + EXPECT_EQ(15, area.Width()); + EXPECT_EQ(15, area.Height()); } { @@ -518,8 +517,8 @@ WebGestureEvent scaled_gesture_event = TransformWebGestureEvent(view, web_gesture_event); IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame()); - EXPECT_EQ(10, area.Width()); - EXPECT_EQ(10, area.Height()); + EXPECT_EQ(15, area.Width()); + EXPECT_EQ(15, area.Height()); } { @@ -536,10 +535,10 @@ EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().x); EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().y); - EXPECT_FLOAT_EQ(30, transformed_event.PositionInWidget().x); - EXPECT_FLOAT_EQ(30, transformed_event.PositionInWidget().y); - EXPECT_FLOAT_EQ(10, transformed_event.width); - EXPECT_FLOAT_EQ(10, transformed_event.height); + EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().x); + EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().y); + EXPECT_FLOAT_EQ(15, transformed_event.width); + EXPECT_FLOAT_EQ(15, transformed_event.height); } { @@ -569,18 +568,18 @@ coalescedevents[0].WebPointerEventInRootFrame(); EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().x); EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().y); - EXPECT_FLOAT_EQ(30, transformed_event.PositionInWidget().x); - EXPECT_FLOAT_EQ(30, transformed_event.PositionInWidget().y); - EXPECT_FLOAT_EQ(10, transformed_event.width); - EXPECT_FLOAT_EQ(10, transformed_event.height); + EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().x); + EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().y); + EXPECT_FLOAT_EQ(15, transformed_event.width); + EXPECT_FLOAT_EQ(15, transformed_event.height); transformed_event = coalescedevents[1].WebPointerEventInRootFrame(); EXPECT_FLOAT_EQ(120, transformed_event.PositionInScreen().x); EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().y); - EXPECT_FLOAT_EQ(40, transformed_event.PositionInWidget().x); - EXPECT_FLOAT_EQ(30, transformed_event.PositionInWidget().y); - EXPECT_FLOAT_EQ(20, transformed_event.width); - EXPECT_FLOAT_EQ(10, transformed_event.height); + EXPECT_FLOAT_EQ(60, transformed_event.PositionInWidget().x); + EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().y); + EXPECT_FLOAT_EQ(30, transformed_event.width); + EXPECT_FLOAT_EQ(15, transformed_event.height); } }
diff --git a/third_party/blink/renderer/core/exported/web_document_loader_impl.cc b/third_party/blink/renderer/core/exported/web_document_loader_impl.cc index b4fcf64..955b59da 100644 --- a/third_party/blink/renderer/core/exported/web_document_loader_impl.cc +++ b/third_party/blink/renderer/core/exported/web_document_loader_impl.cc
@@ -53,8 +53,16 @@ return DocumentLoader::WillLoadUrlAsEmpty(url); } -const WebURLRequest& WebDocumentLoaderImpl::OriginalRequest() const { - return original_request_wrapper_; +WebURL WebDocumentLoaderImpl::OriginalUrl() const { + return DocumentLoader::OriginalUrl(); +} + +WebString WebDocumentLoaderImpl::OriginalReferrer() const { + return DocumentLoader::OriginalReferrer(); +} + +WebURL WebDocumentLoaderImpl::GetUrl() const { + return request_wrapper_.Url(); } const WebURLRequest& WebDocumentLoaderImpl::GetRequest() const { @@ -106,11 +114,8 @@ LocalFrame* frame, WebNavigationType navigation_type, std::unique_ptr<WebNavigationParams> navigation_params) - : DocumentLoader(frame, - navigation_type, - std::move(navigation_params)), - original_request_wrapper_(DocumentLoader::OriginalRequest()), - request_wrapper_(DocumentLoader::GetRequest()), + : DocumentLoader(frame, navigation_type, std::move(navigation_params)), + request_wrapper_(request_), response_wrapper_(DocumentLoader::GetResponse()) {} WebDocumentLoaderImpl::~WebDocumentLoaderImpl() {
diff --git a/third_party/blink/renderer/core/exported/web_document_loader_impl.h b/third_party/blink/renderer/core/exported/web_document_loader_impl.h index 43889dd4..aee6f16 100644 --- a/third_party/blink/renderer/core/exported/web_document_loader_impl.h +++ b/third_party/blink/renderer/core/exported/web_document_loader_impl.h
@@ -58,7 +58,9 @@ } // WebDocumentLoader methods: - const WebURLRequest& OriginalRequest() const override; + WebURL OriginalUrl() const override; + WebString OriginalReferrer() const override; + WebURL GetUrl() const override; const WebURLRequest& GetRequest() const override; const WebURLResponse& GetResponse() const override; bool HasUnreachableURL() const override; @@ -90,7 +92,6 @@ // Mutable because the const getters will magically sync these to the // latest version from WebKit. - mutable WrappedResourceRequest original_request_wrapper_; mutable WrappedResourceRequest request_wrapper_; mutable WrappedResourceResponse response_wrapper_;
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc index 45e4e61..db616e7 100644 --- a/third_party/blink/renderer/core/exported/web_frame_test.cc +++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -4551,7 +4551,7 @@ web_view_helper.LocalMainFrame()->GetDocumentLoader(); ASSERT_TRUE(document_loader); EXPECT_EQ(ToKURL(base_url_ + "fixed_layout.html"), - KURL(document_loader->GetRequest().Url())); + KURL(document_loader->GetUrl())); } TEST_F(WebFrameTest, AppendRedirects) { @@ -8010,8 +8010,8 @@ cc::Layer* cc_scroll_layer = scroll_layer->CcLayer(); // Verify that the cc::Layer is not scrollable initially. - ASSERT_FALSE(cc_scroll_layer->user_scrollable_horizontal()); - ASSERT_FALSE(cc_scroll_layer->user_scrollable_vertical()); + ASSERT_FALSE(cc_scroll_layer->GetUserScrollableHorizontal()); + ASSERT_FALSE(cc_scroll_layer->GetUserScrollableVertical()); // Call javascript to make the layer scrollable, and verify it. WebLocalFrameImpl* frame = web_view_helper.LocalMainFrame(); @@ -8020,8 +8020,8 @@ scroll_layer = compositor->ScrollLayer(); cc_scroll_layer = scroll_layer->CcLayer(); - ASSERT_TRUE(cc_scroll_layer->user_scrollable_horizontal()); - ASSERT_TRUE(cc_scroll_layer->user_scrollable_vertical()); + ASSERT_TRUE(cc_scroll_layer->GetUserScrollableHorizontal()); + ASSERT_TRUE(cc_scroll_layer->GetUserScrollableVertical()); } // Test that currentHistoryItem reflects the current page, not the provisional @@ -8311,13 +8311,13 @@ frame_view->GetPage()->GetVisualViewport().ScrollLayer(); ASSERT_FALSE( - layout_viewport_scroll_layer->CcLayer()->user_scrollable_horizontal()); + layout_viewport_scroll_layer->CcLayer()->GetUserScrollableHorizontal()); ASSERT_FALSE( - layout_viewport_scroll_layer->CcLayer()->user_scrollable_vertical()); + layout_viewport_scroll_layer->CcLayer()->GetUserScrollableVertical()); ASSERT_FALSE( - visual_viewport_scroll_layer->CcLayer()->user_scrollable_horizontal()); + visual_viewport_scroll_layer->CcLayer()->GetUserScrollableHorizontal()); ASSERT_FALSE( - visual_viewport_scroll_layer->CcLayer()->user_scrollable_vertical()); + visual_viewport_scroll_layer->CcLayer()->GetUserScrollableVertical()); // Verify that the viewports are scrollable upon exiting fullscreen. EXPECT_EQ(div_fullscreen, Fullscreen::FullscreenElementFrom(*document)); @@ -8329,13 +8329,13 @@ visual_viewport_scroll_layer = frame_view->GetPage()->GetVisualViewport().ScrollLayer(); ASSERT_TRUE( - layout_viewport_scroll_layer->CcLayer()->user_scrollable_horizontal()); + layout_viewport_scroll_layer->CcLayer()->GetUserScrollableHorizontal()); ASSERT_TRUE( - layout_viewport_scroll_layer->CcLayer()->user_scrollable_vertical()); + layout_viewport_scroll_layer->CcLayer()->GetUserScrollableVertical()); ASSERT_TRUE( - visual_viewport_scroll_layer->CcLayer()->user_scrollable_horizontal()); + visual_viewport_scroll_layer->CcLayer()->GetUserScrollableHorizontal()); ASSERT_TRUE( - visual_viewport_scroll_layer->CcLayer()->user_scrollable_vertical()); + visual_viewport_scroll_layer->CcLayer()->GetUserScrollableVertical()); } TEST_F(WebFrameTest, FullscreenMainFrame) { @@ -8356,8 +8356,8 @@ ->LayerForScrolling() ->CcLayer(); ASSERT_TRUE(cc_scroll_layer->scrollable()); - ASSERT_TRUE(cc_scroll_layer->user_scrollable_horizontal()); - ASSERT_TRUE(cc_scroll_layer->user_scrollable_vertical()); + ASSERT_TRUE(cc_scroll_layer->GetUserScrollableHorizontal()); + ASSERT_TRUE(cc_scroll_layer->GetUserScrollableVertical()); LocalFrame* frame = web_view_impl->MainFrameImpl()->GetFrame(); Document* document = frame->GetDocument(); @@ -8381,14 +8381,14 @@ ->LayerForScrolling() ->CcLayer(); ASSERT_TRUE(cc_scroll_layer->scrollable()); - ASSERT_TRUE(cc_scroll_layer->user_scrollable_horizontal()); - ASSERT_TRUE(cc_scroll_layer->user_scrollable_vertical()); + ASSERT_TRUE(cc_scroll_layer->GetUserScrollableHorizontal()); + ASSERT_TRUE(cc_scroll_layer->GetUserScrollableVertical()); // Verify the main frame still behaves correctly after a resize. web_view_helper.Resize(WebSize(viewport_height, viewport_width)); ASSERT_TRUE(cc_scroll_layer->scrollable()); - ASSERT_TRUE(cc_scroll_layer->user_scrollable_horizontal()); - ASSERT_TRUE(cc_scroll_layer->user_scrollable_vertical()); + ASSERT_TRUE(cc_scroll_layer->GetUserScrollableHorizontal()); + ASSERT_TRUE(cc_scroll_layer->GetUserScrollableVertical()); } TEST_F(WebFrameTest, FullscreenSubframe) {
diff --git a/third_party/blink/renderer/core/fetch/request.cc b/third_party/blink/renderer/core/fetch/request.cc index 01ed44e3..1dcaf5c 100644 --- a/third_party/blink/renderer/core/fetch/request.cc +++ b/third_party/blink/renderer/core/fetch/request.cc
@@ -677,7 +677,7 @@ return request_->Method(); } -KURL Request::url() const { +const KURL& Request::url() const { return request_->Url(); }
diff --git a/third_party/blink/renderer/core/fetch/request.h b/third_party/blink/renderer/core/fetch/request.h index 0885cac0..acb74c1 100644 --- a/third_party/blink/renderer/core/fetch/request.h +++ b/third_party/blink/renderer/core/fetch/request.h
@@ -65,7 +65,7 @@ // From Request.idl: String method() const; - KURL url() const; + const KURL& url() const; Headers* getHeaders() const { return headers_; } String destination() const; String referrer() const;
diff --git a/third_party/blink/renderer/core/fileapi/file_reader_loader_client.h b/third_party/blink/renderer/core/fileapi/file_reader_loader_client.h index 747a254..6b5da43 100644 --- a/third_party/blink/renderer/core/fileapi/file_reader_loader_client.h +++ b/third_party/blink/renderer/core/fileapi/file_reader_loader_client.h
@@ -38,6 +38,8 @@ enum class FileErrorCode; +// For more information on how to read Blobs in your specific situation, see: +// https://chromium.googlesource.com/chromium/src/+/HEAD/storage/browser/blob/README.md#accessing-reading class CORE_EXPORT FileReaderLoaderClient { public: virtual ~FileReaderLoaderClient() = default;
diff --git a/third_party/blink/renderer/core/frame/frame_overlay_test.cc b/third_party/blink/renderer/core/frame/frame_overlay_test.cc index 3452ec07..e4e8251 100644 --- a/third_party/blink/renderer/core/frame/frame_overlay_test.cc +++ b/third_party/blink/renderer/core/frame/frame_overlay_test.cc
@@ -34,9 +34,6 @@ namespace blink { namespace { -static const int kViewportWidth = 800; -static const int kViewportHeight = 600; - // FrameOverlay that paints a solid color. class SolidColorOverlay : public FrameOverlay::Delegate { public: @@ -60,6 +57,9 @@ class FrameOverlayTest : public testing::Test { protected: + static constexpr int kViewportWidth = 800; + static constexpr int kViewportHeight = 600; + FrameOverlayTest() { helper_.Initialize(nullptr /* web_frame_client */, nullptr /* web_view_client */,
diff --git a/third_party/blink/renderer/core/frame/history.cc b/third_party/blink/renderer/core/frame/history.cc index 5446de4..3292326 100644 --- a/third_party/blink/renderer/core/frame/history.cc +++ b/third_party/blink/renderer/core/frame/history.cc
@@ -213,7 +213,6 @@ ExceptionState& exception_state) { StateObjectAdded(std::move(data), title, url, ScrollRestorationInternal(), WebFrameLoadType::kStandard, exception_state); - UseCounter::Count(GetFrame(), WebFeature::kHistoryPushState); } void History::replaceState(scoped_refptr<SerializedScriptValue> data, @@ -222,7 +221,6 @@ ExceptionState& exception_state) { StateObjectAdded(std::move(data), title, url, ScrollRestorationInternal(), WebFrameLoadType::kReplaceCurrentItem, exception_state); - UseCounter::Count(GetFrame(), WebFeature::kHistoryReplaceState); } KURL History::UrlForState(const String& url_string) {
diff --git a/third_party/blink/renderer/core/frame/history.idl b/third_party/blink/renderer/core/frame/history.idl index 376d6c5..1d3633d 100644 --- a/third_party/blink/renderer/core/frame/history.idl +++ b/third_party/blink/renderer/core/frame/history.idl
@@ -28,13 +28,13 @@ enum ScrollRestoration {"auto", "manual"}; interface History { - [RaisesException] readonly attribute unsigned long length; + [MeasureAs=HistoryLength, RaisesException] readonly attribute unsigned long length; [Measure, RaisesException] attribute ScrollRestoration scrollRestoration; // TODO(foolip): The SerializedScriptValue type should be any. [CachedAttribute=stateChanged, RaisesException] readonly attribute SerializedScriptValue state; [CallWith=ScriptState, RaisesException] void go(optional long delta = 0); [CallWith=ScriptState, RaisesException] void back(); [CallWith=ScriptState, RaisesException] void forward(); - [RaisesException] void pushState(SerializedScriptValue data, DOMString title, optional DOMString? url = null); - [RaisesException] void replaceState(SerializedScriptValue data, DOMString title, optional DOMString? url = null); + [MeasureAs=HistoryPushState, RaisesException] void pushState(SerializedScriptValue data, DOMString title, optional DOMString? url = null); + [MeasureAs=HistoryReplaceState, RaisesException] void replaceState(SerializedScriptValue data, DOMString title, optional DOMString? url = null); };
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 99178cbc5..dda99e3b 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -1700,4 +1700,11 @@ frame_color_overlay_->Paint(context); } +void LocalFrame::ForciblyPurgeV8Memory() { + // TODO(yuzus): Implement ContextMummified callback and call from here. + WindowProxyManager* window_proxy_manager = GetWindowProxyManager(); + window_proxy_manager->ClearForV8MemoryPurge(); + Loader().StopAllLoaders(); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index cdfe168..79bf183 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -425,6 +425,9 @@ // For CompositeAfterPaint. void PaintFrameColorOverlay(GraphicsContext&); + // To be called from OomInterventionImpl. + void ForciblyPurgeV8Memory(); + private: friend class FrameNavigationDisabler;
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 027fe5a..ebb437c0 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -222,7 +222,6 @@ is_visually_non_empty_(false), fragment_anchor_(nullptr), sticky_position_object_count_(0), - input_events_scale_factor_for_emulation_(1), layout_size_fixed_to_frame_size_(true), needs_update_geometries_(false), root_layer_did_scroll_(false), @@ -1990,14 +1989,10 @@ probe::didResizeMainFrame(frame_.Get()); } -void LocalFrameView::SetInputEventsScaleForEmulation( - float content_scale_factor) { - input_events_scale_factor_for_emulation_ = content_scale_factor; -} - float LocalFrameView::InputEventsScaleFactor() const { float page_scale = frame_->GetPage()->GetVisualViewport().Scale(); - return page_scale * input_events_scale_factor_for_emulation_; + return page_scale * + frame_->GetPage()->GetChromeClient().InputEventsScaleForEmulation(); } void LocalFrameView::NotifyPageThatContentAreaWillPaint() const {
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 b957bd72..35a2c9d 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.h +++ b/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -260,9 +260,6 @@ // Scale used to convert incoming input events. float InputEventsScaleFactor() const; - // Scale used to convert incoming input events while emulating device metics. - void SetInputEventsScaleForEmulation(float); - void DidChangeScrollOffset(); void ViewportSizeChanged(bool width_changed, bool height_changed); @@ -912,8 +909,6 @@ ObjectSet background_attachment_fixed_objects_; Member<FrameViewAutoSizeInfo> auto_size_info_; - float input_events_scale_factor_for_emulation_; - IntSize layout_size_; IntSize initial_viewport_size_; bool layout_size_fixed_to_frame_size_;
diff --git a/third_party/blink/renderer/core/frame/screen.idl b/third_party/blink/renderer/core/frame/screen.idl index 44dee75..2e7e9c3 100644 --- a/third_party/blink/renderer/core/frame/screen.idl +++ b/third_party/blink/renderer/core/frame/screen.idl
@@ -31,14 +31,14 @@ [ Exposed=Window ] interface Screen { - readonly attribute long availWidth; - readonly attribute long availHeight; - readonly attribute long width; - readonly attribute long height; - readonly attribute unsigned long colorDepth; - readonly attribute unsigned long pixelDepth; + [HighEntropy, Measure] readonly attribute long availWidth; + [HighEntropy, Measure] readonly attribute long availHeight; + [HighEntropy, Measure] readonly attribute long width; + [HighEntropy, Measure] readonly attribute long height; + [HighEntropy, Measure] readonly attribute unsigned long colorDepth; + [HighEntropy, Measure] readonly attribute unsigned long pixelDepth; // Non-standard - [Measure] readonly attribute long availLeft; - [Measure] readonly attribute long availTop; + [HighEntropy, Measure] readonly attribute long availLeft; + [HighEntropy, Measure] readonly attribute long availTop; };
diff --git a/third_party/blink/renderer/core/frame/visual_viewport.cc b/third_party/blink/renderer/core/frame/visual_viewport.cc index 51b1e64df..e3c41b6 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport.cc +++ b/third_party/blink/renderer/core/frame/visual_viewport.cc
@@ -530,6 +530,9 @@ } void VisualViewport::CreateLayerTree() { + if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) + return; + if (inner_viewport_scroll_layer_) return; @@ -555,7 +558,8 @@ ScrollingCoordinator* coordinator = GetPage().GetScrollingCoordinator(); DCHECK(coordinator); inner_viewport_scroll_layer_->SetIsContainerForFixedPositionLayers(true); - coordinator->UpdateUserInputScrollable(this); + if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) + coordinator->UpdateUserInputScrollable(this); // Set masks to bounds so the compositor doesn't clobber a manually // set inner viewport container layer size.
diff --git a/third_party/blink/renderer/core/frame/visual_viewport.idl b/third_party/blink/renderer/core/frame/visual_viewport.idl index 00317b9..4d64ea5 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport.idl +++ b/third_party/blink/renderer/core/frame/visual_viewport.idl
@@ -29,16 +29,16 @@ [ ImplementedAs=DOMVisualViewport ] interface VisualViewport : EventTarget { - [Measure] readonly attribute double offsetLeft; - [Measure] readonly attribute double offsetTop; + [HighEntropy, Measure] readonly attribute double offsetLeft; + [HighEntropy, Measure] readonly attribute double offsetTop; - [Measure] readonly attribute double pageLeft; - [Measure] readonly attribute double pageTop; + [HighEntropy, Measure] readonly attribute double pageLeft; + [HighEntropy, Measure] readonly attribute double pageTop; - [Measure] readonly attribute double width; - [Measure] readonly attribute double height; + [HighEntropy, Measure] readonly attribute double width; + [HighEntropy, Measure] readonly attribute double height; - [Measure] readonly attribute double scale; + [HighEntropy, Measure] readonly attribute double scale; attribute EventHandler onresize; attribute EventHandler onscroll;
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 a827875..a6ab698 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport_test.cc +++ b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
@@ -867,8 +867,12 @@ UpdateAllLifecyclePhases(); // Ensure the scroll contents size matches the frame view's size. - EXPECT_EQ(IntSize(320, 240), IntSize(visual_viewport.ScrollLayer()->Size())); - if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) { + if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { + EXPECT_EQ(IntSize(320, 240), + IntSize(visual_viewport.ScrollLayer()->Size())); + } + if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled() || + RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { EXPECT_EQ(IntSize(320, 240), visual_viewport.GetScrollNode()->ContentsSize()); } @@ -1636,6 +1640,9 @@ // layer when hideScrollbars WebSetting is true. TEST_P(VisualViewportTest, TestScrollbarsNotAttachedWhenHideScrollbarsSettingIsTrue) { + if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) + return; + InitializeWithAndroidSettings(configureHiddenScrollbarsSettings); WebView()->MainFrameWidget()->Resize(IntSize(100, 150)); NavigateTo("about:blank"); @@ -1649,6 +1656,9 @@ // layer when hideScrollbars WebSetting is false. TEST_P(VisualViewportTest, TestScrollbarsAttachedWhenHideScrollbarsSettingIsFalse) { + if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) + return; + InitializeWithAndroidSettings(); WebView()->MainFrameWidget()->Resize(IntSize(100, 150)); NavigateTo("about:blank");
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index 8f71d93..ac58bf7 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -1733,7 +1733,6 @@ local_frame_client_(LocalFrameClientImpl::Create(this)), autofill_client_(nullptr), find_in_page_(FindInPage::Create(*this, interface_registry)), - input_events_scale_factor_for_emulation_(1), interface_registry_(interface_registry), input_method_controller_(*this), spell_check_panel_host_client_(nullptr), @@ -1877,8 +1876,6 @@ web_view->MaxAutoSize()); } - GetFrame()->View()->SetInputEventsScaleForEmulation( - input_events_scale_factor_for_emulation_); GetFrame()->View()->SetDisplayMode(web_view->DisplayMode()); if (frame_widget_) @@ -1937,15 +1934,6 @@ Client()->DidFinishLoad(); } -void WebLocalFrameImpl::SetInputEventsScaleForEmulation( - float content_scale_factor) { - input_events_scale_factor_for_emulation_ = content_scale_factor; - if (GetFrame()->View()) { - GetFrame()->View()->SetInputEventsScaleForEmulation( - input_events_scale_factor_for_emulation_); - } -} - HitTestResult WebLocalFrameImpl::HitTestResultForVisualViewportPos( const IntPoint& pos_in_viewport) { IntPoint root_frame_point(
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h index c0012590a..344e3801 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -395,8 +395,6 @@ return content_settings_client_; } - void SetInputEventsScaleForEmulation(float); - WebTextCheckClient* GetTextCheckerClient() const { return text_check_client_; } @@ -474,10 +472,6 @@ // information. Is used by PrintPage(). Member<ChromePrintContext> print_context_; - // Stores the additional input events scale when device metrics - // emulation is enabled. - float input_events_scale_factor_for_emulation_; - // Borrowed pointers to Mojo objects. blink::InterfaceRegistry* interface_registry_;
diff --git a/third_party/blink/renderer/core/frame/window.idl b/third_party/blink/renderer/core/frame/window.idl index d002cd3..093b5ea6 100644 --- a/third_party/blink/renderer/core/frame/window.idl +++ b/third_party/blink/renderer/core/frame/window.idl
@@ -127,7 +127,7 @@ // CSSOM View Module // https://drafts.csswg.org/cssom-view/#extensions-to-the-window-interface - [NewObject] MediaQueryList matchMedia(DOMString query); + [HighEntropy, Measure, NewObject] MediaQueryList matchMedia(DOMString query); [SameObject, Replaceable] readonly attribute Screen screen; [RuntimeEnabled=WorkerTaskQueue, SameObject, Replaceable] readonly attribute ScriptedTaskQueueController TaskQueue; @@ -139,14 +139,14 @@ void resizeBy(long x, long y); // viewport - [Affects=Nothing, Replaceable] readonly attribute long innerWidth; - [Affects=Nothing, Replaceable] readonly attribute long innerHeight; + [Affects=Nothing, HighEntropy, MeasureAs=WindowInnerWidth, Replaceable] readonly attribute long innerWidth; + [Affects=Nothing, HighEntropy, MeasureAs=WindowInnerHeight, Replaceable] readonly attribute long innerHeight; // viewport scrolling - [Replaceable] readonly attribute double scrollX; - [Replaceable] readonly attribute double pageXOffset; - [Replaceable] readonly attribute double scrollY; - [Replaceable] readonly attribute double pageYOffset; + [HighEntropy, MeasureAs=WindowScrollX, Replaceable] readonly attribute double scrollX; + [HighEntropy, MeasureAs=WindowPageXOffset, Replaceable] readonly attribute double pageXOffset; + [HighEntropy, MeasureAs=WindowScrollY, Replaceable] readonly attribute double scrollY; + [HighEntropy, MeasureAs=WindowPageYOffset, Replaceable] readonly attribute double pageYOffset; void scroll(optional ScrollToOptions options); void scroll(unrestricted double x, unrestricted double y); void scrollTo(optional ScrollToOptions options); @@ -159,11 +159,11 @@ [Replaceable, SameObject] readonly attribute VisualViewport visualViewport; // client - [Affects=Nothing, Replaceable] readonly attribute long screenX; - [Affects=Nothing, Replaceable] readonly attribute long screenY; - [Affects=Nothing, Replaceable] readonly attribute long outerWidth; - [Affects=Nothing, Replaceable] readonly attribute long outerHeight; - [Affects=Nothing, Replaceable] readonly attribute double devicePixelRatio; + [Affects=Nothing, HighEntropy, MeasureAs=WindowScreenX, Replaceable] readonly attribute long screenX; + [Affects=Nothing, HighEntropy, MeasureAs=WindowScreenY, Replaceable] readonly attribute long screenY; + [Affects=Nothing, HighEntropy, MeasureAs=WindowOuterWidth, Replaceable] readonly attribute long outerWidth; + [Affects=Nothing, HighEntropy, MeasureAs=WindowOuterHeight, Replaceable] readonly attribute long outerHeight; + [Affects=Nothing, HighEntropy, MeasureAs=WindowDevicePixelRatio, Replaceable] readonly attribute double devicePixelRatio; // Selection API // https://w3c.github.io/selection-api/#extensions-to-window-interface @@ -181,7 +181,7 @@ // This is the interface orientation in degrees. Some examples are: // 0 is straight up; -90 is when the device is rotated 90 clockwise; // 90 is when rotated counter clockwise. - [MeasureAs=WindowOrientation, RuntimeEnabled=OrientationEvent] readonly attribute long orientation; + [HighEntropy, MeasureAs=WindowOrientation, RuntimeEnabled=OrientationEvent] readonly attribute long orientation; // Accessibility Object Model // https://github.com/WICG/aom/blob/HEAD/explainer.md @@ -201,8 +201,8 @@ [Default=Undefined] optional boolean searchInFrames, [Default=Undefined] optional boolean showDialog); [MeasureAs=WindowOffscreenBuffering, Replaceable, NotEnumerable] readonly attribute boolean offscreenBuffering; - [MeasureAs=WindowScreenLeft, Replaceable] readonly attribute long screenLeft; - [MeasureAs=WindowScreenTop, Replaceable] readonly attribute long screenTop; + [HighEntropy, MeasureAs=WindowScreenLeft, Replaceable] readonly attribute long screenLeft; + [HighEntropy, MeasureAs=WindowScreenTop, Replaceable] readonly attribute long screenTop; [MeasureAs=WindowDefaultStatus] attribute DOMString defaultStatus; [MeasureAs=WindowDefaultstatus, ImplementedAs=defaultStatus] attribute DOMString defaultstatus; [MeasureAs=StyleMedia] readonly attribute StyleMedia styleMedia; @@ -226,7 +226,7 @@ attribute DOMMatrixConstructor WebKitCSSMatrix; - //TrustedTypes API: http://github.com/wicg/trusted-types + // TrustedTypes API: http://github.com/wicg/trusted-types [RuntimeEnabled=TrustedDOMTypes, Unforgeable] readonly attribute TrustedTypePolicyFactory TrustedTypes; };
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.idl b/third_party/blink/renderer/core/html/canvas/html_canvas_element.idl index 609b8bd..f62bc324 100644 --- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.idl +++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.idl
@@ -37,11 +37,11 @@ // Note: The arguments argument is variadic in the spec, but not here as // only one extra argument is actually used. // FIXME: type should not have a default value. - [MeasureAs=CanvasToDataURL, RaisesException] DOMString toDataURL(optional DOMString type = null, optional any arguments); + [HighEntropy, MeasureAs=CanvasToDataURL, RaisesException] DOMString toDataURL(optional DOMString type = null, optional any arguments); - [MeasureAs=CanvasToBlob, RaisesException] void toBlob(BlobCallback _callback, optional DOMString type = null, optional any arguments); + [HighEntropy, MeasureAs=CanvasToBlob, RaisesException] void toBlob(BlobCallback _callback, optional DOMString type = null, optional any arguments); - [RuntimeEnabled=CanvasColorManagement, MeasureAs=CanvasConvertToBlob, RaisesException, CallWith=ScriptState] Promise<Blob> convertToBlob(optional ImageEncodeOptions options); + [HighEntropy, RuntimeEnabled=CanvasColorManagement, MeasureAs=CanvasConvertToBlob, RaisesException, CallWith=ScriptState] Promise<Blob> convertToBlob(optional ImageEncodeOptions options); }; // https://html.spec.whatwg.org/multipage/canvas.html#blobcallback
diff --git a/third_party/blink/renderer/core/html/html_frame_element_base.cc b/third_party/blink/renderer/core/html/html_frame_element_base.cc index 14734c34..9124cd0 100644 --- a/third_party/blink/renderer/core/html/html_frame_element_base.cc +++ b/third_party/blink/renderer/core/html/html_frame_element_base.cc
@@ -86,39 +86,8 @@ if (!parent_frame) return; - // Support for <frame src="javascript:string"> - KURL script_url; KURL url = GetDocument().CompleteURL(url_); - if (url.ProtocolIsJavaScript()) { - // We'll set/execute |scriptURL| iff CSP allows us to execute inline - // JavaScript. If CSP blocks inline JavaScript, then exit early if - // we're trying to execute script in an existing document. If we're - // executing JavaScript to create a new document (e.g. - // '<iframe src="javascript:...">' then continue loading 'about:blank' - // so that the frame is populated with something reasonable. - if (ContentSecurityPolicy::ShouldBypassMainWorld(&GetDocument()) || - GetDocument().GetContentSecurityPolicy()->AllowJavaScriptURLs( - this, url.GetString(), GetDocument().Url(), - OrdinalNumber::First())) { - script_url = url; - } else { - if (ContentFrame()) - return; - } - - url = BlankURL(); - } - - if (!LoadOrRedirectSubframe(url, frame_name_, replace_current_item)) - return; - if (!ContentFrame() || script_url.IsEmpty() || - !ContentFrame()->IsLocalFrame()) - return; - if (ContentFrame()->Owner()->GetSandboxFlags() & kSandboxOrigin) - return; - ToLocalFrame(ContentFrame()) - ->GetScriptController() - .ExecuteScriptIfJavaScriptURL(script_url, this); + LoadOrRedirectSubframe(url, frame_name_, replace_current_item); } void HTMLFrameElementBase::ParseAttribute(
diff --git a/third_party/blink/renderer/core/html/html_frame_owner_element.cc b/third_party/blink/renderer/core/html/html_frame_owner_element.cc index 905f9f6d..59af84e 100644 --- a/third_party/blink/renderer/core/html/html_frame_owner_element.cc +++ b/third_party/blink/renderer/core/html/html_frame_owner_element.cc
@@ -453,6 +453,15 @@ } } + // If we're executing JavaScript to create a new document (e.g. '<iframe + // src="javascript:...">') then continue loading 'about:blank' so that the + // frame is populated with something reasonable. + if (url.ProtocolIsJavaScript()) { + ResourceRequest blank_request(BlankURL()); + child_frame->Loader().StartNavigation( + FrameLoadRequest(&GetDocument(), blank_request), child_load_type); + } + child_frame->Loader().StartNavigation( FrameLoadRequest(&GetDocument(), request), child_load_type);
diff --git a/third_party/blink/renderer/core/html/html_image_element_test.cc b/third_party/blink/renderer/core/html/html_image_element_test.cc index 1e3ae678..a84a3d1d 100644 --- a/third_party/blink/renderer/core/html/html_image_element_test.cc +++ b/third_party/blink/renderer/core/html/html_image_element_test.cc
@@ -12,15 +12,20 @@ namespace blink { -const int kViewportWidth = 500; -const int kViewportHeight = 600; class HTMLImageElementTest : public PageTestBase { protected: + static constexpr int kViewportWidth = 500; + static constexpr int kViewportHeight = 600; + void SetUp() override { PageTestBase::SetUp(IntSize(kViewportWidth, kViewportHeight)); } }; +// Instantiate class constants. Not needed after C++17. +constexpr int HTMLImageElementTest::kViewportWidth; +constexpr int HTMLImageElementTest::kViewportHeight; + TEST_F(HTMLImageElementTest, width) { auto* image = HTMLImageElement::Create(GetDocument()); image->setAttribute(html_names::kWidthAttr, "400");
diff --git a/third_party/blink/renderer/core/html/html_link_element.cc b/third_party/blink/renderer/core/html/html_link_element.cc index 8b8de076..374c5fa5 100644 --- a/third_party/blink/renderer/core/html/html_link_element.cc +++ b/third_party/blink/renderer/core/html/html_link_element.cc
@@ -41,6 +41,7 @@ #include "third_party/blink/renderer/core/html/link_manifest.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/inspector/console_message.h" +#include "third_party/blink/renderer/core/loader/link_loader.h" #include "third_party/blink/renderer/core/loader/network_hints_interface.h" #include "third_party/blink/renderer/core/origin_trials/origin_trials.h" #include "third_party/blink/renderer/platform/weborigin/security_policy.h"
diff --git a/third_party/blink/renderer/core/html/html_link_element.h b/third_party/blink/renderer/core/html/html_link_element.h index 89f69258..57fb644 100644 --- a/third_party/blink/renderer/core/html/html_link_element.h +++ b/third_party/blink/renderer/core/html/html_link_element.h
@@ -35,7 +35,6 @@ #include "third_party/blink/renderer/core/html/link_resource.h" #include "third_party/blink/renderer/core/html/link_style.h" #include "third_party/blink/renderer/core/html/rel_list.h" -#include "third_party/blink/renderer/core/loader/link_loader.h" #include "third_party/blink/renderer/core/loader/link_loader_client.h" #include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h" @@ -44,6 +43,7 @@ class KURL; class LinkImport; +class LinkLoader; struct LinkLoadParameters; class CORE_EXPORT HTMLLinkElement final : public HTMLElement,
diff --git a/third_party/blink/renderer/core/html/link_style.cc b/third_party/blink/renderer/core/html/link_style.cc index 6b1ffa1..1fd0665 100644 --- a/third_party/blink/renderer/core/html/link_style.cc +++ b/third_party/blink/renderer/core/html/link_style.cc
@@ -14,6 +14,7 @@ #include "third_party/blink/renderer/core/html/html_link_element.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/loader/importance_attribute.h" +#include "third_party/blink/renderer/core/loader/link_load_parameters.h" #include "third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h" #include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h" #include "third_party/blink/renderer/platform/histogram.h"
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 d4f5fed..8fb1fb3 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
@@ -85,6 +85,7 @@ #include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/core/layout/intersection_geometry.h" #include "third_party/blink/renderer/core/layout/layout_media.h" +#include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h" @@ -102,6 +103,7 @@ #include "third_party/blink/renderer/platform/network/parsed_content_type.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" #include "third_party/blink/renderer/platform/wtf/text/cstring.h" #include "third_party/blink/renderer/platform/wtf/time.h" @@ -133,8 +135,6 @@ namespace { constexpr float kMostlyFillViewportThreshold = 0.85f; -constexpr TimeDelta kCheckViewportIntersectionInterval = - TimeDelta::FromSeconds(1); // This enum is used to record histograms. Do not reorder. enum MediaControlsShow { @@ -463,10 +463,6 @@ audio_tracks_timer_(document.GetTaskRunner(TaskType::kInternalMedia), this, &HTMLMediaElement::AudioTracksTimerFired), - check_viewport_intersection_timer_( - document.GetTaskRunner(TaskType::kInternalMedia), - this, - &HTMLMediaElement::CheckViewportIntersectionTimerFired), removed_from_document_timer_( document.GetTaskRunner(TaskType::kInternalMedia), this, @@ -567,8 +563,10 @@ GetDocument().GetTaskRunner(TaskType::kInternalMedia)); audio_tracks_timer_.MoveToNewTaskRunner( GetDocument().GetTaskRunner(TaskType::kInternalMedia)); - check_viewport_intersection_timer_.MoveToNewTaskRunner( - GetDocument().GetTaskRunner(TaskType::kInternalMedia)); + if (viewport_intersection_observer_) { + ActivateViewportIntersectionMonitoring(false); + ActivateViewportIntersectionMonitoring(true); + } deferred_load_timer_.MoveToNewTaskRunner( GetDocument().GetTaskRunner(TaskType::kInternalMedia)); removed_from_document_timer_.MoveToNewTaskRunner( @@ -3546,7 +3544,6 @@ void HTMLMediaElement::StopPeriodicTimers() { progress_event_timer_.Stop(); playback_progress_timer_.Stop(); - check_viewport_intersection_timer_.Stop(); if (lazy_load_visibility_observer_) { lazy_load_visibility_observer_->Stop(); lazy_load_visibility_observer_ = nullptr; @@ -3974,6 +3971,7 @@ } void HTMLMediaElement::Trace(blink::Visitor* visitor) { + visitor->Trace(viewport_intersection_observer_); visitor->Trace(played_time_ranges_); visitor->Trace(async_event_queue_); visitor->Trace(error_); @@ -4222,11 +4220,17 @@ } void HTMLMediaElement::ActivateViewportIntersectionMonitoring(bool activate) { - if (activate && !check_viewport_intersection_timer_.IsActive()) { - check_viewport_intersection_timer_.StartRepeating( - kCheckViewportIntersectionInterval, FROM_HERE); - } else if (!activate) { - check_viewport_intersection_timer_.Stop(); + if (activate && !viewport_intersection_observer_) { + viewport_intersection_observer_ = IntersectionObserver::Create( + {}, {kMostlyFillViewportThreshold}, &(GetDocument()), + WTF::BindRepeating(&HTMLMediaElement::OnViewportIntersectionChanged, + WrapWeakPersistent(this)), + IntersectionObserver::kFractionOfRoot); + viewport_intersection_observer_->observe(this); + } else if (!activate && viewport_intersection_observer_) { + viewport_intersection_observer_->disconnect(); + viewport_intersection_observer_ = nullptr; + mostly_filling_viewport_ = false; } } @@ -4269,19 +4273,10 @@ EffectivePreloadType() != WebMediaPlayer::kPreloadNone; } -void HTMLMediaElement::CheckViewportIntersectionTimerFired(TimerBase*) { - bool should_report_root_bounds = true; - IntersectionGeometry geometry(nullptr, *this, Vector<Length>(), - should_report_root_bounds); - geometry.ComputeGeometry(); - IntRect intersect_rect = geometry.IntersectionIntRect(); - if (current_intersect_rect_ == intersect_rect) - return; - - current_intersect_rect_ = intersect_rect; - bool is_mostly_filling_viewport = - (current_intersect_rect_.Size().Area() > - kMostlyFillViewportThreshold * geometry.RootIntRect().Size().Area()); +void HTMLMediaElement::OnViewportIntersectionChanged( + const HeapVector<Member<IntersectionObserverEntry>>& entries) { + const bool is_mostly_filling_viewport = + (entries.back()->intersectionRatio() >= kMostlyFillViewportThreshold); if (mostly_filling_viewport_ == is_mostly_filling_viewport) return;
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.h b/third_party/blink/renderer/core/html/media/html_media_element.h index 4b46a71f..7b2d04b 100644 --- a/third_party/blink/renderer/core/html/media/html_media_element.h +++ b/third_party/blink/renderer/core/html/media/html_media_element.h
@@ -38,6 +38,7 @@ #include "third_party/blink/renderer/core/dom/pausable_object.h" #include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/html/media/media_controls.h" +#include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h" #include "third_party/blink/renderer/platform/audio/audio_source_provider.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h" @@ -442,7 +443,8 @@ void ProgressEventTimerFired(TimerBase*); void PlaybackProgressTimerFired(TimerBase*); void ScheduleTimeupdateEvent(bool periodic_event); - void CheckViewportIntersectionTimerFired(TimerBase*); + void OnViewportIntersectionChanged( + const HeapVector<Member<IntersectionObserverEntry>>& entries); void StartPlaybackProgressTimer(); void StartProgressEventTimer(); void StopPeriodicTimers(); @@ -561,9 +563,10 @@ TaskRunnerTimer<HTMLMediaElement> progress_event_timer_; TaskRunnerTimer<HTMLMediaElement> playback_progress_timer_; TaskRunnerTimer<HTMLMediaElement> audio_tracks_timer_; - TaskRunnerTimer<HTMLMediaElement> check_viewport_intersection_timer_; TaskRunnerTimer<HTMLMediaElement> removed_from_document_timer_; + Member<IntersectionObserver> viewport_intersection_observer_; + Member<TimeRanges> played_time_ranges_; Member<EventQueue> async_event_queue_; @@ -657,6 +660,8 @@ bool processing_preference_change_ : 1; bool playing_remotely_ : 1; + // The following is always false unless viewport intersection monitoring is + // turned on via ActivateViewportIntersectionMonitoring(). bool mostly_filling_viewport_ : 1; bool was_always_muted_ : 1; @@ -747,8 +752,6 @@ WebRemotePlaybackClient* remote_playback_client_; - IntRect current_intersect_rect_; - Member<MediaControls> media_controls_; Member<HTMLMediaElementControlsList> controls_list_;
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.idl b/third_party/blink/renderer/core/html/media/html_media_element.idl index 3fa256d76..c568bcf 100644 --- a/third_party/blink/renderer/core/html/media/html_media_element.idl +++ b/third_party/blink/renderer/core/html/media/html_media_element.idl
@@ -49,7 +49,7 @@ [CEReactions] attribute DOMString preload; readonly attribute TimeRanges buffered; void load(); - CanPlayTypeResult canPlayType(DOMString type); + [HighEntropy, Measure] CanPlayTypeResult canPlayType(DOMString type); // ready state const unsigned short HAVE_NOTHING = 0;
diff --git a/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc b/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc index 5077394..5456e9fd 100644 --- a/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc +++ b/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc
@@ -123,6 +123,8 @@ void MediaCustomControlsFullscreenDetector:: OnCheckViewportIntersectionTimerFired(TimerBase*) { DCHECK(IsVideoOrParentFullscreen()); + + // TODO(crbug.com/906258): This can cause a crash when DCHECKs are enabled! IntersectionGeometry geometry(nullptr, VideoElement(), Vector<Length>(), true); geometry.ComputeGeometry();
diff --git a/third_party/blink/renderer/core/html/media_element_filling_viewport_test.cc b/third_party/blink/renderer/core/html/media_element_filling_viewport_test.cc index 31c4298..0be52ad 100644 --- a/third_party/blink/renderer/core/html/media_element_filling_viewport_test.cc +++ b/third_party/blink/renderer/core/html/media_element_filling_viewport_test.cc
@@ -27,11 +27,15 @@ return element->mostly_filling_viewport_; } - void CheckViewportIntersectionChanged(HTMLMediaElement* element) { - element->ActivateViewportIntersectionMonitoring(true); - EXPECT_TRUE(element->check_viewport_intersection_timer_.IsActive()); - // TODO(xjz): Mock the time and wait for 1s instead. - element->CheckViewportIntersectionTimerFired(nullptr); + void ActivateViewportIntersectionMonitoring(HTMLMediaElement* element, + bool enable) { + element->ActivateViewportIntersectionMonitoring(enable); + EXPECT_EQ(enable, !!element->viewport_intersection_observer_); + } + + void DoCompositeAndPropagate() { + Compositor().BeginFrame(); + test::RunPendingTasks(); } std::unique_ptr<SimRequest> CreateMainResource() { @@ -57,8 +61,14 @@ HTMLMediaElement* element = ToElement<HTMLMediaElement>(GetDocument().getElementById("video")); - CheckViewportIntersectionChanged(element); + + ActivateViewportIntersectionMonitoring(element, true); + DoCompositeAndPropagate(); EXPECT_TRUE(IsMostlyFillingViewport(element)); + + ActivateViewportIntersectionMonitoring(element, false); + DoCompositeAndPropagate(); + EXPECT_FALSE(IsMostlyFillingViewport(element)); } TEST_F(MediaElementFillingViewportTest, NotMostlyFillingViewport) { @@ -76,7 +86,8 @@ HTMLMediaElement* element = ToElement<HTMLMediaElement>(GetDocument().getElementById("video")); - CheckViewportIntersectionChanged(element); + ActivateViewportIntersectionMonitoring(element, true); + DoCompositeAndPropagate(); EXPECT_FALSE(IsMostlyFillingViewport(element)); } @@ -95,15 +106,15 @@ HTMLMediaElement* element = ToElement<HTMLMediaElement>(GetDocument().getElementById("video")); - CheckViewportIntersectionChanged(element); + + ActivateViewportIntersectionMonitoring(element, true); + DoCompositeAndPropagate(); EXPECT_TRUE(IsMostlyFillingViewport(element)); element->setAttribute("style", "position:fixed; left:0; top:0; width:80%; height:80%;", ASSERT_NO_EXCEPTION); - Compositor().BeginFrame(); - - CheckViewportIntersectionChanged(element); + DoCompositeAndPropagate(); EXPECT_FALSE(IsMostlyFillingViewport(element)); } @@ -122,7 +133,9 @@ HTMLMediaElement* element = ToElement<HTMLMediaElement>(GetDocument().getElementById("video")); - CheckViewportIntersectionChanged(element); + + ActivateViewportIntersectionMonitoring(element, true); + DoCompositeAndPropagate(); EXPECT_TRUE(IsMostlyFillingViewport(element)); } @@ -141,14 +154,15 @@ HTMLMediaElement* element = ToElement<HTMLMediaElement>(GetDocument().getElementById("video")); - CheckViewportIntersectionChanged(element); + + ActivateViewportIntersectionMonitoring(element, true); + DoCompositeAndPropagate(); EXPECT_TRUE(IsMostlyFillingViewport(element)); element->setAttribute( "style", "position:fixed; left:0; top:240px; width:100%; height:100%;", ASSERT_NO_EXCEPTION); - Compositor().BeginFrame(); - CheckViewportIntersectionChanged(element); + DoCompositeAndPropagate(); EXPECT_FALSE(IsMostlyFillingViewport(element)); }
diff --git a/third_party/blink/renderer/core/html/parser/html_document_parser.cc b/third_party/blink/renderer/core/html/parser/html_document_parser.cc index 6624165f..2f4a5f5 100644 --- a/third_party/blink/renderer/core/html/parser/html_document_parser.cc +++ b/third_party/blink/renderer/core/html/parser/html_document_parser.cc
@@ -47,8 +47,8 @@ #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/inspector/inspector_trace_events.h" #include "third_party/blink/renderer/core/loader/document_loader.h" -#include "third_party/blink/renderer/core/loader/link_loader.h" #include "third_party/blink/renderer/core/loader/navigation_scheduler.h" +#include "third_party/blink/renderer/core/loader/preload_helper.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/script/html_parser_script_runner.h" #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h" @@ -322,7 +322,7 @@ // Note that on commit, the loader dispatched preloads for all the non-media // links. GetDocument()->Loader()->DispatchLinkHeaderPreloads( - &chunk->viewport, LinkLoader::kOnlyLoadMedia); + &chunk->viewport, PreloadHelper::kOnlyLoadMedia); tried_loading_link_headers_ = true; }
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc index 66727b3..1d4f8c9 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
@@ -53,7 +53,7 @@ #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/input_type_names.h" #include "third_party/blink/renderer/core/loader/importance_attribute.h" -#include "third_party/blink/renderer/core/loader/link_loader.h" +#include "third_party/blink/renderer/core/loader/preload_helper.h" #include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h" #include "third_party/blink/renderer/core/script/script_loader.h" #include "third_party/blink/renderer/platform/histogram.h" @@ -555,7 +555,7 @@ base::Optional<ResourceType> ResourceTypeForLinkPreload() const { DCHECK(link_is_preload_); - return LinkLoader::GetResourceTypeFromAsAttribute(as_attribute_value_); + return PreloadHelper::GetResourceTypeFromAsAttribute(as_attribute_value_); } ResourceType GetResourceType() const {
diff --git a/third_party/blink/renderer/core/html/parser/preload_request.cc b/third_party/blink/renderer/core/html/parser/preload_request.cc index 6182fd8..889dbb73 100644 --- a/third_party/blink/renderer/core/html/parser/preload_request.cc +++ b/third_party/blink/renderer/core/html/parser/preload_request.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/loader/document_loader.h" -#include "third_party/blink/renderer/core/loader/link_loader.h" +#include "third_party/blink/renderer/core/loader/preload_helper.h" #include "third_party/blink/renderer/core/script/document_write_intervention.h" #include "third_party/blink/renderer/core/script/script_loader.h" #include "third_party/blink/renderer/platform/cross_origin_attribute_value.h" @@ -114,7 +114,8 @@ } } - return LinkLoader::StartPreload(resource_type_, params, document->Fetcher()); + return PreloadHelper::StartPreload(resource_type_, params, + document->Fetcher()); } } // namespace blink
diff --git a/third_party/blink/renderer/core/html/parser/xss_auditor.cc b/third_party/blink/renderer/core/html/parser/xss_auditor.cc index 0ed6267..05e8e9f 100644 --- a/third_party/blink/renderer/core/html/parser/xss_auditor.cc +++ b/third_party/blink/renderer/core/html/parser/xss_auditor.cc
@@ -454,7 +454,7 @@ if (auditor_delegate) auditor_delegate->SetReportURL(xss_protection_report_url.Copy()); - EncodedFormData* http_body = document_loader->GetRequest().HttpBody(); + EncodedFormData* http_body = document_loader->HttpBody(); if (http_body && !http_body->IsEmpty()) http_body_as_string_ = http_body->FlattenToString(); }
diff --git a/third_party/blink/renderer/core/html/parser/xss_auditor_delegate.cc b/third_party/blink/renderer/core/html/parser/xss_auditor_delegate.cc index 609c93215..79a977e7 100644 --- a/third_party/blink/renderer/core/html/parser/xss_auditor_delegate.cc +++ b/third_party/blink/renderer/core/html/parser/xss_auditor_delegate.cc
@@ -84,7 +84,7 @@ String http_body; if (frame_loader.GetDocumentLoader()) { if (EncodedFormData* form_data = - frame_loader.GetDocumentLoader()->OriginalRequest().HttpBody()) + frame_loader.GetDocumentLoader()->HttpBody()) http_body = form_data->FlattenToString(); }
diff --git a/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc b/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc index c0f40a7..d42f29e 100644 --- a/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc +++ b/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc
@@ -421,21 +421,6 @@ UpdateRootLayerTransform(); } -void DevToolsEmulator::ApplyDeviceEmulationTransform( - TransformationMatrix* transform) { - if (device_metrics_enabled_) { - transform->Scale(emulation_params_.scale); - if (web_view_->MainFrameImpl()) { - web_view_->MainFrameImpl()->SetInputEventsScaleForEmulation( - emulation_params_.scale); - } - } else { - if (web_view_->MainFrameImpl()) { - web_view_->MainFrameImpl()->SetInputEventsScaleForEmulation(1.0); - } - } -} - void DevToolsEmulator::ApplyViewportOverride(TransformationMatrix* transform) { if (!viewport_override_) return; @@ -467,7 +452,8 @@ // Apply device emulation transform first, so that it is affected by the // viewport override. ApplyViewportOverride(&transform); - ApplyDeviceEmulationTransform(&transform); + if (device_metrics_enabled_) + transform.Scale(emulation_params_.scale); web_view_->SetDeviceEmulationTransform(transform); } @@ -484,6 +470,10 @@ viewport_size.Width(), viewport_size.Height())); } +float DevToolsEmulator::InputEventsScaleForEmulation() { + return device_metrics_enabled_ ? emulation_params_.scale : 1.0; +} + void DevToolsEmulator::SetTouchEventEmulationEnabled(bool enabled, int max_touch_points) { if (!touch_event_emulation_enabled_) {
diff --git a/third_party/blink/renderer/core/inspector/dev_tools_emulator.h b/third_party/blink/renderer/core/inspector/dev_tools_emulator.h index 0d3d98f..b9680b1 100644 --- a/third_party/blink/renderer/core/inspector/dev_tools_emulator.h +++ b/third_party/blink/renderer/core/inspector/dev_tools_emulator.h
@@ -66,6 +66,10 @@ // This ensures that all content inside the forced viewport is painted. base::Optional<IntRect> VisibleContentRectForPainting() const; + // Returns the scale used to convert incoming input events while emulating + // device metics. + float InputEventsScaleForEmulation(); + private: void EnableMobileEmulation(); void DisableMobileEmulation(); @@ -74,7 +78,6 @@ // deviceScaleFactor() otherwise. float CompositorDeviceScaleFactor() const; - void ApplyDeviceEmulationTransform(TransformationMatrix*); void ApplyViewportOverride(TransformationMatrix*); void UpdateRootLayerTransform();
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 0188270..0f302c6 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
@@ -369,6 +369,10 @@ } PaintLayerCompositor* InspectorLayerTreeAgent::GetPaintLayerCompositor() { + // TODO(crbug.com/916768): Implement the feature. + if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) + return nullptr; + auto* layout_view = inspected_frames_->Root()->ContentLayoutObject(); PaintLayerCompositor* compositor = layout_view ? layout_view->Compositor() : nullptr;
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc index dc7d6da..74331df 100644 --- a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
@@ -1020,14 +1020,14 @@ std::unique_ptr<protocol::Page::Frame> InspectorPageAgent::BuildObjectForFrame( LocalFrame* frame) { DocumentLoader* loader = frame->Loader().GetDocumentLoader(); - KURL url = loader->GetRequest().Url(); std::unique_ptr<protocol::Page::Frame> frame_object = protocol::Page::Frame::create() .setId(IdentifiersFactory::FrameId(frame)) .setLoaderId(IdentifiersFactory::LoaderId(loader)) - .setUrl(UrlWithoutFragment(url).GetString()) + .setUrl(UrlWithoutFragment(loader->Url()).GetString()) .setMimeType(frame->Loader().GetDocumentLoader()->MimeType()) - .setSecurityOrigin(SecurityOrigin::Create(url)->ToRawString()) + .setSecurityOrigin( + SecurityOrigin::Create(loader->Url())->ToRawString()) .build(); Frame* parent_frame = frame->Tree().Parent(); if (parent_frame) {
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc index 0d2bd92..8b392c7 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc +++ b/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc
@@ -60,8 +60,12 @@ DOMHighResTimeStamp timestamp = observer_->GetTimeStamp(); if (timestamp == -1) return; - if (timestamp - last_run_time_ < observer_->GetEffectiveDelay()) + if (timestamp - last_run_time_ < observer_->GetEffectiveDelay()) { + // TODO(crbug.com/915495): Need to eventually notify the observer of the + // updated intersection because there's currently nothing to guarantee this + // Compute() method will be called again after the delay period has passed. return; + } last_run_time_ = timestamp; needs_update_ = 0; Vector<Length> root_margin(4); @@ -92,15 +96,19 @@ float new_visible_ratio; bool is_visible = false; if (geometry.DoesIntersect()) { - if (geometry.TargetRect().IsEmpty()) { + const LayoutRect comparison_rect = observer_->trackFractionOfRoot() + ? geometry.RootRect() + : geometry.TargetRect(); + if (comparison_rect.IsEmpty()) { new_visible_ratio = 1; } else { - float intersection_area = - geometry.IntersectionRect().Size().Width().ToFloat() * - geometry.IntersectionRect().Size().Height().ToFloat(); - float target_area = geometry.TargetRect().Size().Width().ToFloat() * - geometry.TargetRect().Size().Height().ToFloat(); - new_visible_ratio = intersection_area / target_area; + const LayoutSize& intersection_size = geometry.IntersectionRect().Size(); + const float intersection_area = intersection_size.Width().ToFloat() * + intersection_size.Height().ToFloat(); + const LayoutSize& comparison_size = comparison_rect.Size(); + const float area_of_interest = comparison_size.Width().ToFloat() * + comparison_size.Height().ToFloat(); + new_visible_ratio = intersection_area / area_of_interest; } new_threshold_index = Observer()->FirstThresholdGreaterThan(new_visible_ratio);
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc index 44d25d3b..527e8e3 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc +++ b/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc
@@ -176,7 +176,8 @@ return nullptr; return MakeGarbageCollected<IntersectionObserver>( - delegate, root, root_margin, thresholds, delay, track_visibility); + delegate, root, root_margin, thresholds, kFractionOfTarget, delay, + track_visibility); } IntersectionObserver* IntersectionObserver::Create( @@ -195,6 +196,7 @@ const Vector<float>& thresholds, Document* document, EventCallback callback, + ThresholdInterpretation semantics, DOMHighResTimeStamp delay, bool track_visibility, ExceptionState& exception_state) { @@ -202,8 +204,8 @@ MakeGarbageCollected<IntersectionObserverDelegateImpl>( document, std::move(callback)); return MakeGarbageCollected<IntersectionObserver>( - *intersection_observer_delegate, nullptr, root_margin, thresholds, delay, - track_visibility); + *intersection_observer_delegate, nullptr, root_margin, thresholds, + semantics, delay, track_visibility); } IntersectionObserver::IntersectionObserver( @@ -211,6 +213,7 @@ Element* root, const Vector<Length>& root_margin, const Vector<float>& thresholds, + ThresholdInterpretation semantics, DOMHighResTimeStamp delay, bool track_visibility) : ContextClient(delegate.GetExecutionContext()), @@ -223,7 +226,8 @@ bottom_margin_(kFixed), left_margin_(kFixed), root_is_implicit_(root ? 0 : 1), - track_visibility_(track_visibility ? 1 : 0) { + track_visibility_(track_visibility ? 1 : 0), + track_fraction_of_root_(semantics == kFractionOfRoot) { switch (root_margin.size()) { case 0: break;
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observer.h b/third_party/blink/renderer/core/intersection_observer/intersection_observer.h index 395e53d..082a306 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_observer.h +++ b/third_party/blink/renderer/core/intersection_observer/intersection_observer.h
@@ -39,6 +39,24 @@ using EventCallback = base::RepeatingCallback<void( const HeapVector<Member<IntersectionObserverEntry>>&)>; + // The IntersectionObserver can be configured to notify based on changes to + // how much of the target element's area intersects with the root, or based on + // changes to how much of the root element's area intersects with the + // target. Examples illustrating the distinction: + // + // 1.0 of target, 0.5 of target, 1.0 of target, + // 0.25 of root 0.5 of root 1.0 of root + // +------------------+ +------------------+ *~~~~~~~~~~~~~~~~~~* + // | ////////// | | | ;//////////////////; + // | ////////// | | | ;//////////////////; + // | ////////// | ;//////////////////; ;//////////////////; + // | | ;//////////////////; ;//////////////////; + // +------------------+ *~~~~~~~~~~~~~~~~~~* *~~~~~~~~~~~~~~~~~~* + // //////////////////// + // //////////////////// + // //////////////////// + enum ThresholdInterpretation { kFractionOfTarget, kFractionOfRoot }; + static IntersectionObserver* Create(const IntersectionObserverInit*, IntersectionObserverDelegate&, ExceptionState&); @@ -46,19 +64,32 @@ V8IntersectionObserverCallback*, const IntersectionObserverInit*, ExceptionState&); - static IntersectionObserver* Create(const Vector<Length>& root_margin, - const Vector<float>& thresholds, - Document*, - EventCallback, - DOMHighResTimeStamp delay = 0, - bool track_visbility = false, - ExceptionState& = ASSERT_NO_EXCEPTION); + + // Creates an IntersectionObserver that monitors changes to the intersection + // between its target element relative to its implicit root and notifies via + // the given |callback|. |thresholds| should be in the range [0,1], and are + // interpreted according to the given |semantics|. |delay| specifies the + // minimum period between change notifications. + // + // TODO(crbug.com/915495): The |delay| feature is broken. See comments in + // intersection_observation.cc. + static IntersectionObserver* Create( + const Vector<Length>& root_margin, + const Vector<float>& thresholds, + Document* document, + EventCallback callback, + ThresholdInterpretation semantics = kFractionOfTarget, + DOMHighResTimeStamp delay = 0, + bool track_visbility = false, + ExceptionState& = ASSERT_NO_EXCEPTION); + static void ResumeSuspendedObservers(); explicit IntersectionObserver(IntersectionObserverDelegate&, Element*, const Vector<Length>& root_margin, const Vector<float>& thresholds, + ThresholdInterpretation semantics, DOMHighResTimeStamp delay, bool track_visibility); @@ -74,6 +105,7 @@ const Vector<float>& thresholds() const { return thresholds_; } DOMHighResTimeStamp delay() const { return delay_; } bool trackVisibility() const { return track_visibility_; } + bool trackFractionOfRoot() const { return track_fraction_of_root_; } // An observer can either track intersections with an explicit root Element, // or with the the top-level frame's viewport (the "implicit root"). When @@ -118,6 +150,7 @@ Length left_margin_; unsigned root_is_implicit_ : 1; unsigned track_visibility_ : 1; + unsigned track_fraction_of_root_ : 1; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc index ebe67a8..fe1d444 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc +++ b/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc
@@ -18,7 +18,6 @@ #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/wtf/time.h" - namespace blink { namespace { @@ -144,6 +143,68 @@ EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting()); } +TEST_F(IntersectionObserverTest, ReportsFractionOfTargetOrRoot) { + // Place a 100x100 target element in the middle of a 200x200 main frame. + WebView().MainFrameWidget()->Resize(WebSize(200, 200)); + SimRequest main_resource("https://example.com/", "text/html"); + LoadURL("https://example.com/"); + main_resource.Complete(R"HTML( + <style> + #target { + position: absolute; + top: 50px; left: 50px; width: 100px; height: 100px; + } + </style> + <div id='target'></div> + )HTML"); + + Element* target = GetDocument().getElementById("target"); + ASSERT_TRUE(target); + + // 100% of the target element's area intersects with the frame. + constexpr float kExpectedFractionOfTarget = 1.0f; + + // 25% of the frame's area is covered by the target element. + constexpr float kExpectedFractionOfRoot = 0.25f; + + TestIntersectionObserverDelegate* target_observer_delegate = + MakeGarbageCollected<TestIntersectionObserverDelegate>(GetDocument()); + IntersectionObserver* target_observer = + MakeGarbageCollected<IntersectionObserver>( + *target_observer_delegate, nullptr, Vector<Length>(), + Vector<float>{kExpectedFractionOfTarget / 2}, + IntersectionObserver::kFractionOfTarget, 0, false); + DummyExceptionStateForTesting exception_state; + target_observer->observe(target, exception_state); + ASSERT_FALSE(exception_state.HadException()); + + TestIntersectionObserverDelegate* root_observer_delegate = + MakeGarbageCollected<TestIntersectionObserverDelegate>(GetDocument()); + IntersectionObserver* root_observer = + MakeGarbageCollected<IntersectionObserver>( + *root_observer_delegate, nullptr, Vector<Length>(), + Vector<float>{kExpectedFractionOfRoot / 2}, + IntersectionObserver::kFractionOfRoot, 0, false); + root_observer->observe(target, exception_state); + ASSERT_FALSE(exception_state.HadException()); + + Compositor().BeginFrame(); + test::RunPendingTasks(); + ASSERT_FALSE(Compositor().NeedsBeginFrame()); + + EXPECT_EQ(target_observer_delegate->CallCount(), 1); + EXPECT_EQ(target_observer_delegate->EntryCount(), 1); + EXPECT_TRUE(target_observer_delegate->LastEntry()->isIntersecting()); + EXPECT_NEAR(kExpectedFractionOfTarget, + target_observer_delegate->LastEntry()->intersectionRatio(), 1e-6); + + EXPECT_EQ(root_observer_delegate->CallCount(), 1); + EXPECT_EQ(root_observer_delegate->EntryCount(), 1); + EXPECT_TRUE(root_observer_delegate->LastEntry()->isIntersecting()); + EXPECT_NEAR(kExpectedFractionOfRoot, + root_observer_delegate->LastEntry()->intersectionRatio(), 1e-6); +} + TEST_F(IntersectionObserverTest, ResumePostsTask) { WebView().MainFrameWidget()->Resize(WebSize(800, 600)); SimRequest main_resource("https://example.com/", "text/html");
diff --git a/third_party/blink/renderer/core/layout/layout_tree_as_text.cc b/third_party/blink/renderer/core/layout/layout_tree_as_text.cc index ab89c956..59f5a4e9 100644 --- a/third_party/blink/renderer/core/layout/layout_tree_as_text.cc +++ b/third_party/blink/renderer/core/layout/layout_tree_as_text.cc
@@ -683,6 +683,9 @@ } } + if ((behavior & kLayoutAsTextShowPaintProperties) && layer.NeedsRepaint()) + ts << " needsRepaint"; + ts << "\n"; if (paint_phase != kLayerPaintPhaseBackground) @@ -709,13 +712,20 @@ // Calculate the clip rects we should use. LayoutRect layer_bounds; ClipRect damage_rect, clip_rect_to_apply; - layer->Clipper(PaintLayer::kUseGeometryMapper) - .CalculateRects( - ClipRectsContext(root_layer, - &root_layer->GetLayoutObject().FirstFragment(), - kUncachedClipRects), - &layer->GetLayoutObject().FirstFragment(), nullptr, layer_bounds, - damage_rect, clip_rect_to_apply); + if (layer->GetLayoutObject().FirstFragment().HasLocalBorderBoxProperties()) { + layer->Clipper(PaintLayer::kUseGeometryMapper) + .CalculateRects( + ClipRectsContext(root_layer, + &root_layer->GetLayoutObject().FirstFragment(), + kUncachedClipRects), + &layer->GetLayoutObject().FirstFragment(), nullptr, layer_bounds, + damage_rect, clip_rect_to_apply); + } else { + layer->Clipper(PaintLayer::kDoNotUseGeometryMapper) + .CalculateRects( + ClipRectsContext(root_layer, nullptr, kUncachedClipRects), nullptr, + nullptr, layer_bounds, damage_rect, clip_rect_to_apply); + } LayoutPoint offset_from_root; layer->ConvertToLayerCoords(root_layer, offset_from_root);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc index 776dbe0..0025d7f 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc
@@ -49,13 +49,28 @@ } #endif +unsigned NGLineInfo::InflowEndOffset() const { + const NGInlineItemResults& item_results = Results(); + for (auto it = item_results.rbegin(); it != item_results.rend(); ++it) { + const NGInlineItemResult& item_result = *it; + DCHECK(item_result.item); + const NGInlineItem& item = *item_result.item; + if (item.Type() == NGInlineItem::kText || + item.Type() == NGInlineItem::kControl || + item.Type() == NGInlineItem::kAtomicInline) + return item_result.end_offset; + } + return StartOffset(); +} + LayoutUnit NGLineInfo::ComputeTrailingSpaceWidth( unsigned* end_offset_out) const { - // TODO(kojii): Consider adding a flag to skip this function when not needed. - // In many common cases, NGLineBreaker knows that there are no trailing - // spaces, so we can leverage the knowledge without adding the cost to compute - // the flag. We use this function only for 'text-align: justify', so the cost - // to compute the flag should not be more expensive than it benefits. + if (!has_trailing_spaces_) { + if (end_offset_out) + *end_offset_out = InflowEndOffset(); + return LayoutUnit(); + } + const NGInlineItemResults& item_results = Results(); LayoutUnit trailing_spaces_width; for (auto it = item_results.rbegin(); it != item_results.rend(); ++it) {
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h index 2ce6795..db73f1b 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h
@@ -180,6 +180,9 @@ // without clamping. LayoutUnit ComputeWidth() const; + bool HasTrailingSpaces() const { return has_trailing_spaces_; } + void SetHasTrailingSpaces() { has_trailing_spaces_ = true; } + // True if this line has overflow, excluding preserved trailing spaces. bool HasOverflow() const { return has_overflow_; } void SetHasOverflow() { has_overflow_ = true; } @@ -193,6 +196,10 @@ // Start text offset of this line. unsigned StartOffset() const { return start_offset_; } void SetStartOffset(unsigned offset) { start_offset_ = offset; } + // End text offset of this line, excluding out-of-flow objects such as + // floating or positioned. + unsigned InflowEndOffset() const; + // End item index of this line. unsigned EndItemIndex() const { return end_item_index_; } void SetEndItemIndex(unsigned index) { end_item_index_ = index; } @@ -229,6 +236,7 @@ bool is_last_line_ = false; bool is_empty_line_ = false; bool has_overflow_ = false; + bool has_trailing_spaces_ = false; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc index e6b3122..5c1aec2 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
@@ -245,7 +245,9 @@ typename OffsetMappingBuilder::SourceNodeScope scope(&mapping_builder_, nullptr); AppendBreakOpportunity(style, layout_object); - items_->back().SetIsGenerated(); + NGInlineItem* item = &items_->back(); + item->SetIsGenerated(); + item->SetEndCollapseType(NGInlineItem::kOpaqueToCollapsing); } template <typename OffsetMappingBuilder>
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc index 1db2e86..d8ff7ee 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
@@ -192,8 +192,7 @@ PrepareNextLine(); BreakLine(); - if (!trailing_spaces_collapsed_) - RemoveTrailingCollapsibleSpace(); + RemoveTrailingCollapsibleSpace(); #if DCHECK_IS_ON() for (const auto& result : *item_results_) @@ -216,6 +215,9 @@ if (!should_create_line_box) line_info_->SetIsEmptyLine(); line_info_->SetEndItemIndex(item_index_); + DCHECK_NE(trailing_whitespace_, WhitespaceState::kUnknown); + if (trailing_whitespace_ == WhitespaceState::kPreserved) + line_info_->SetHasTrailingSpaces(); ComputeLineLocation(); @@ -225,7 +227,8 @@ void NGLineBreaker::BreakLine() { const Vector<NGInlineItem>& items = Items(); - state_ = LineBreakState::kLeading; + state_ = LineBreakState::kContinue; + trailing_whitespace_ = WhitespaceState::kLeading; while (state_ != LineBreakState::kDone) { // Check overflow even if |item_index_| is at the end of the block, because // the last item of the block may have caused overflow. In that case, @@ -342,8 +345,7 @@ // Skip leading collapsible spaces. // Most cases such spaces are handled as trailing spaces of the previous line, // but there are some cases doing so is too complex. - if (state_ == LineBreakState::kLeading) { - state_ = LineBreakState::kContinue; + if (trailing_whitespace_ == WhitespaceState::kLeading) { if (item.Style()->CollapseWhiteSpace() && Text()[offset_] == kSpaceCharacter) { // Skipping one whitespace removes all collapsible spaces because @@ -355,6 +357,7 @@ return; } } + // |trailing_whitespace_| will be updated as we read the text. } NGInlineItemResult* item_result = AddItem(item); @@ -492,10 +495,20 @@ // beyond the end. if (item_result->end_offset < item.EndOffset()) { item_result->can_break_after = true; + + DCHECK_EQ(break_iterator_.BreakSpace(), BreakSpaceType::kBeforeSpaceRun); + if (UNLIKELY(break_iterator_.BreakType() == + LineBreakType::kBreakCharacter)) { + trailing_whitespace_ = WhitespaceState::kUnknown; + } else { + DCHECK_NE(Text()[item_result->end_offset - 1], kSpaceCharacter); + trailing_whitespace_ = WhitespaceState::kNone; + } } else { DCHECK_EQ(item_result->end_offset, item.EndOffset()); item_result->can_break_after = break_iterator_.IsBreakable(item_result->end_offset); + trailing_whitespace_ = WhitespaceState::kUnknown; } } @@ -580,7 +593,7 @@ // Skipping one whitespace removes all collapsible spaces because // collapsible spaces are collapsed to single space in NGInlineItemBuilder. offset_++; - trailing_spaces_collapsed_ = true; + trailing_whitespace_ = WhitespaceState::kCollapsed; // Make the last item breakable after, even if it was nowrap. DCHECK(!item_results_->IsEmpty()); @@ -589,7 +602,6 @@ // Find the end of the run of space characters in this item. // Other white space characters (e.g., tab) are not included in this item. DCHECK(style.BreakOnlyAfterWhiteSpace()); - trailing_spaces_collapsed_ = true; unsigned end = offset_; while (end < item.EndOffset() && text[end] == kSpaceCharacter) end++; @@ -611,6 +623,7 @@ item_result->can_break_after = end < text.length() && !IsBreakableSpace(text[end]); offset_ = end; + trailing_whitespace_ = WhitespaceState::kPreserved; } // If non-space characters follow, the line is done. @@ -627,12 +640,10 @@ // Remove trailing collapsible spaces in |line_info|. // https://drafts.csswg.org/css-text-3/#white-space-phase-2 void NGLineBreaker::RemoveTrailingCollapsibleSpace() { - DCHECK(!trailing_spaces_collapsed_); - ComputeTrailingCollapsibleSpace(); - trailing_spaces_collapsed_ = true; - if (!trailing_collapsible_space_.has_value()) + if (!trailing_collapsible_space_.has_value()) { return; + } // We have a trailing collapsible space. Remove it. NGInlineItemResult* item_result = trailing_collapsible_space_->item_result; @@ -648,13 +659,11 @@ item_results_->erase(item_result); } trailing_collapsible_space_.reset(); + trailing_whitespace_ = WhitespaceState::kCollapsed; } // Compute the width of trailing spaces without removing it. LayoutUnit NGLineBreaker::TrailingCollapsibleSpaceWidth() { - if (trailing_spaces_collapsed_) - return LayoutUnit(); - ComputeTrailingCollapsibleSpace(); if (!trailing_collapsible_space_.has_value()) return LayoutUnit(); @@ -672,35 +681,59 @@ // Find trailing collapsible space if exists. The result is cached to // |trailing_collapsible_space_|. void NGLineBreaker::ComputeTrailingCollapsibleSpace() { - DCHECK(!trailing_spaces_collapsed_); + if (trailing_whitespace_ == WhitespaceState::kLeading || + trailing_whitespace_ == WhitespaceState::kNone || + trailing_whitespace_ == WhitespaceState::kCollapsed || + trailing_whitespace_ == WhitespaceState::kPreserved) { + trailing_collapsible_space_.reset(); + return; + } + DCHECK(trailing_whitespace_ == WhitespaceState::kUnknown || + trailing_whitespace_ == WhitespaceState::kCollapsible); + trailing_whitespace_ = WhitespaceState::kNone; + const String& text = Text(); for (auto it = item_results_->rbegin(); it != item_results_->rend(); ++it) { NGInlineItemResult& item_result = *it; DCHECK(item_result.item); const NGInlineItem& item = *item_result.item; if (item.EndCollapseType() == NGInlineItem::kOpaqueToCollapsing) continue; - if (item.Type() != NGInlineItem::kText) - break; - DCHECK_GT(item_result.end_offset, 0u); - DCHECK(item.Style()); - if (Text()[item_result.end_offset - 1] != kSpaceCharacter || - !item.Style()->CollapseWhiteSpace() || - // |shape_result| is nullptr if this is an overflow because BreakText() - // uses kNoResultIfOverflow option. - !item_result.shape_result) - break; - - if (!trailing_collapsible_space_.has_value() || - trailing_collapsible_space_->item_result != &item_result) { - trailing_collapsible_space_.emplace(); - trailing_collapsible_space_->item_result = &item_result; - if (item_result.end_offset - 1 > item_result.start_offset) { - trailing_collapsible_space_->collapsed_shape_result = - TruncateLineEndResult(item_result, item_result.end_offset - 1); + if (item.Type() == NGInlineItem::kText) { + DCHECK_GT(item_result.end_offset, 0u); + DCHECK(item.Style()); + if (text[item_result.end_offset - 1] != kSpaceCharacter) + break; + if (!item.Style()->CollapseWhiteSpace()) { + trailing_whitespace_ = WhitespaceState::kPreserved; + break; } + // |shape_result| is nullptr if this is an overflow because BreakText() + // uses kNoResultIfOverflow option. + if (!item_result.shape_result) + break; + + if (!trailing_collapsible_space_.has_value() || + trailing_collapsible_space_->item_result != &item_result) { + trailing_collapsible_space_.emplace(); + trailing_collapsible_space_->item_result = &item_result; + if (item_result.end_offset - 1 > item_result.start_offset) { + trailing_collapsible_space_->collapsed_shape_result = + TruncateLineEndResult(item_result, item_result.end_offset - 1); + } + } + trailing_whitespace_ = WhitespaceState::kCollapsible; + return; } - return; + if (item.Type() == NGInlineItem::kControl) { + UChar character = text[item.StartOffset()]; + if (character == kNewlineCharacter) + continue; + trailing_whitespace_ = WhitespaceState::kPreserved; + trailing_collapsible_space_.reset(); + return; + } + break; } trailing_collapsible_space_.reset(); @@ -842,8 +875,7 @@ ComputeLineMarginsForVisualContainer(constraint_space_, style); item_result->inline_size += item_result->margins.InlineSum(); - if (state_ == LineBreakState::kLeading) - state_ = LineBreakState::kContinue; + trailing_whitespace_ = WhitespaceState::kNone; position_ += item_result->inline_size; ComputeCanBreakAfter(item_result); MoveToNextOf(item); @@ -1141,7 +1173,8 @@ // rewinding all items simplifes the code. if (!item_results_->IsEmpty()) Rewind(0); - state_ = LineBreakState::kLeading; + state_ = LineBreakState::kContinue; + trailing_whitespace_ = WhitespaceState::kLeading; SetCurrentStyle(line_info_->LineStyle()); return; } @@ -1157,6 +1190,7 @@ } if (position_maybe_changed) { + trailing_whitespace_ = WhitespaceState::kUnknown; UpdatePosition(); } @@ -1213,7 +1247,7 @@ item_results.Shrink(new_end); - trailing_spaces_collapsed_ = false; + trailing_whitespace_ = WhitespaceState::kUnknown; trailing_collapsible_space_.reset(); SetLineEndFragment(nullptr); UpdatePosition();
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h index 072e540..1052fb0 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
@@ -61,6 +61,20 @@ const NGConstraintSpace&, NGInlineItemResult*); + // This enum is private, except for |WhitespaceStateForTesting()|. See + // |whitespace_| member. + enum class WhitespaceState { + kLeading, + kNone, + kUnknown, + kCollapsible, + kCollapsed, + kPreserved, + }; + WhitespaceState TrailingWhitespaceForTesting() const { + return trailing_whitespace_; + } + private: const String& Text() const { return items_data_.text_content; } const Vector<NGInlineItem>& Items() const { return items_data_.items; } @@ -86,9 +100,6 @@ // when it is overflowing. kTrailing, - // The initial state, until the first character is found. - kLeading, - // Looking for more items to fit into the current line. kContinue, }; @@ -149,6 +160,10 @@ unsigned item_index_ = 0; unsigned offset_ = 0; + // |WhitespaceState| of the current end. When a line is broken, this indicates + // the state of trailing whitespaces. + WhitespaceState trailing_whitespace_; + // The current position from inline_start. Unlike NGInlineLayoutAlgorithm // that computes position in visual order, this position in logical order. LayoutUnit position_; @@ -184,9 +199,6 @@ // True when the line we are breaking has a list marker. bool has_list_marker_ = false; - // True if trailing collapsible spaces have been collapsed. - bool trailing_spaces_collapsed_ = false; - // Set when the line ended with a forced break. Used to setup the states for // the next line. bool is_after_forced_break_ = false;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc index 50e4672..b4f9af9 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc
@@ -47,6 +47,7 @@ scoped_refptr<NGInlineBreakToken> break_token; Vector<NGLineInfo> line_infos; + trailing_whitespaces_.resize(0); NGExclusionSpace exclusion_space; NGLineLayoutOpportunity line_opportunity(available_width); while (!break_token || !break_token->IsFinished()) { @@ -57,6 +58,8 @@ &exclusion_space, 0u, line_opportunity, break_token.get()); line_breaker.NextLine(&line_info); + trailing_whitespaces_.push_back( + line_breaker.TrailingWhitespaceForTesting()); if (line_info.Results().IsEmpty()) break; @@ -75,6 +78,8 @@ lines.push_back(std::move(line_info.Results())); return lines; } + + Vector<NGLineBreaker::WhitespaceState> trailing_whitespaces_; }; namespace { @@ -320,6 +325,76 @@ EXPECT_EQ("789", ToString(lines[1], node)); } +struct WhitespaceStateTestData { + const char* html; + const char* white_space; + NGLineBreaker::WhitespaceState expected; +} whitespace_state_test_data[] = { + // The most common cases. + {"12", "normal", NGLineBreaker::WhitespaceState::kNone}, + {"1234 5678", "normal", NGLineBreaker::WhitespaceState::kCollapsed}, + // |NGInlineItemsBuilder| collapses trailing spaces of a block, so + // |NGLineBreaker| computes to `none`. + {"12 ", "normal", NGLineBreaker::WhitespaceState::kNone}, + // pre/pre-wrap should preserve trailing spaces if exists. + {"1234 5678", "pre-wrap", NGLineBreaker::WhitespaceState::kPreserved}, + {"12 ", "pre", NGLineBreaker::WhitespaceState::kPreserved}, + {"12 ", "pre-wrap", NGLineBreaker::WhitespaceState::kPreserved}, + {"12", "pre", NGLineBreaker::WhitespaceState::kNone}, + {"12", "pre-wrap", NGLineBreaker::WhitespaceState::kNone}, + // Empty/space-only cases. + {"", "normal", NGLineBreaker::WhitespaceState::kLeading}, + {" ", "pre", NGLineBreaker::WhitespaceState::kPreserved}, + {" ", "pre-wrap", NGLineBreaker::WhitespaceState::kPreserved}, + // Cases needing to rewind. + {"12 34<span>56</span>", "normal", + NGLineBreaker::WhitespaceState::kCollapsed}, + {"12 34<span>56</span>", "pre-wrap", + NGLineBreaker::WhitespaceState::kPreserved}, + // Atomic inlines. + {"12 <span style='display: inline-block'></span>", "normal", + NGLineBreaker::WhitespaceState::kNone}, + // fast/text/whitespace/inline-whitespace-wrapping-4.html + {"<span style='white-space: nowrap'>1234 </span>" + "<span style='white-space: normal'> 5678</span>", + "pre", NGLineBreaker::WhitespaceState::kCollapsed}, +}; + +std::ostream& operator<<(std::ostream& os, + const WhitespaceStateTestData& data) { + return os << static_cast<int>(data.expected) << " for '" << data.html + << "' with 'white-space: " << data.white_space << "'"; +} + +class NGWhitespaceStateTest + : public NGLineBreakerTest, + public testing::WithParamInterface<WhitespaceStateTestData> {}; + +INSTANTIATE_TEST_CASE_P(NGLineBreakerTest, + NGWhitespaceStateTest, + testing::ValuesIn(whitespace_state_test_data)); + +TEST_P(NGWhitespaceStateTest, WhitespaceState) { + const auto& data = GetParam(); + LoadAhem(); + NGInlineNode node = CreateInlineNode(String(R"HTML( + <!DOCTYPE html> + <style> + #container { + font: 10px/1 Ahem; + width: 50px; + white-space: )HTML") + data.white_space + + R"HTML( + } + </style> + <div id=container>)HTML" + data.html + + R"HTML(</div> + )HTML"); + + Vector<NGLineInfo> line_infos = BreakToLineInfo(node, LayoutUnit(50)); + EXPECT_EQ(trailing_whitespaces_[0], data.expected); +} + struct TrailingSpaceWidthTestData { const char* html; const char* white_space;
diff --git a/third_party/blink/renderer/core/loader/BUILD.gn b/third_party/blink/renderer/core/loader/BUILD.gn index eedd6008..7deab887 100644 --- a/third_party/blink/renderer/core/loader/BUILD.gn +++ b/third_party/blink/renderer/core/loader/BUILD.gn
@@ -43,6 +43,8 @@ "importance_attribute.h", "interactive_detector.cc", "interactive_detector.h", + "link_load_parameters.cc", + "link_load_parameters.h", "link_loader.cc", "link_loader.h", "link_loader_client.h", @@ -78,6 +80,8 @@ "network_hints_interface.h", "ping_loader.cc", "ping_loader.h", + "preload_helper.cc", + "preload_helper.h", "prerenderer_client.cc", "prerenderer_client.h", "previews_resource_loading_hints.cc",
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index 4b4261e1..7923777 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -63,8 +63,8 @@ #include "third_party/blink/renderer/core/loader/frame_loader.h" #include "third_party/blink/renderer/core/loader/idleness_detector.h" #include "third_party/blink/renderer/core/loader/interactive_detector.h" -#include "third_party/blink/renderer/core/loader/link_loader.h" #include "third_party/blink/renderer/core/loader/network_hints_interface.h" +#include "third_party/blink/renderer/core/loader/preload_helper.h" #include "third_party/blink/renderer/core/loader/progress_tracker.h" #include "third_party/blink/renderer/core/loader/subresource_filter.h" #include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h" @@ -115,10 +115,11 @@ LocalFrame* frame, WebNavigationType navigation_type, std::unique_ptr<WebNavigationParams> navigation_params) - : frame_(frame), + : request_(navigation_params->request.ToResourceRequest()), + frame_(frame), fetcher_(FrameFetchContext::CreateFetcherFromDocumentLoader(this)), - original_request_(navigation_params->request.ToResourceRequest()), - request_(navigation_params->request.ToResourceRequest()), + original_url_(request_.Url()), + original_referrer_(request_.HttpReferrer()), load_type_(navigation_params->frame_load_type), is_client_redirect_(navigation_params->is_client_redirect), replaces_current_history_item_(false), @@ -244,12 +245,12 @@ return Fetcher()->GetNavigationTimingInfo(); } -const ResourceRequest& DocumentLoader::OriginalRequest() const { - return original_request_; +const KURL& DocumentLoader::OriginalUrl() const { + return original_url_; } -const ResourceRequest& DocumentLoader::GetRequest() const { - return request_; +const AtomicString& DocumentLoader::OriginalReferrer() const { + return original_referrer_; } void DocumentLoader::SetSubresourceFilter( @@ -272,13 +273,13 @@ void DocumentLoader::DispatchLinkHeaderPreloads( ViewportDescriptionWrapper* viewport, - LinkLoader::MediaPreloadPolicy media_policy) { + PreloadHelper::MediaPreloadPolicy media_policy) { DCHECK_GE(state_, kCommitted); - LinkLoader::LoadLinksFromHeader( + PreloadHelper::LoadLinksFromHeader( GetResponse().HttpHeaderField(http_names::kLink), GetResponse().CurrentRequestUrl(), *frame_, frame_->GetDocument(), - NetworkHintsInterfaceImpl(), LinkLoader::kOnlyLoadResources, media_policy, - viewport); + NetworkHintsInterfaceImpl(), PreloadHelper::kOnlyLoadResources, + media_policy, viewport); } void DocumentLoader::DidChangePerformanceTiming() { @@ -328,7 +329,7 @@ } KURL old_url = request_.Url(); - original_request_.SetURL(new_url); + original_url_ = new_url; request_.SetURL(new_url); SetReplacesCurrentHistoryItem(type != WebFrameLoadType::kStandard); if (same_document_navigation_source == kSameDocumentNavigationHistoryApi) { @@ -364,6 +365,14 @@ return UnreachableURL().IsEmpty() ? Url() : UnreachableURL(); } +const AtomicString& DocumentLoader::Referrer() const { + return request_.HttpReferrer(); +} + +EncodedFormData* DocumentLoader::HttpBody() const { + return request_.HttpBody(); +} + void DocumentLoader::SetHistoryItemStateForCommit( HistoryItem* old_item, WebFrameLoadType load_type, @@ -422,9 +431,9 @@ application_cache_host_->FailedLoadingMainResource(); if (resource->GetResourceError().WasBlockedByResponse()) { - probe::didReceiveResourceResponse(frame_->GetDocument(), - MainResourceIdentifier(), this, - resource->GetResponse(), resource); + probe::didReceiveResourceResponse( + probe::ToCoreProbeSink(frame_->GetDocument()), MainResourceIdentifier(), + this, resource->GetResponse(), resource); } LoadFailed(resource->GetResourceError()); @@ -579,9 +588,9 @@ void DocumentLoader::CancelLoadAfterCSPDenied( const ResourceResponse& response) { - probe::didReceiveResourceResponse(frame_->GetDocument(), - MainResourceIdentifier(), this, response, - GetResource()); + probe::didReceiveResourceResponse( + probe::ToCoreProbeSink(frame_->GetDocument()), MainResourceIdentifier(), + this, response, GetResource()); SetWasBlockedAfterCSP(); @@ -593,7 +602,7 @@ ClearResource(); content_security_policy_.Clear(); KURL blocked_url = SecurityOrigin::UrlWithUniqueOpaqueOrigin(); - original_request_.SetURL(blocked_url); + original_url_ = blocked_url; request_.SetURL(blocked_url); redirect_chain_.pop_back(); AppendRedirect(blocked_url); @@ -714,9 +723,9 @@ resource->SetDataBufferingPolicy(kBufferData); if (!ShouldContinueForResponse()) { - probe::didReceiveResourceResponse(frame_->GetDocument(), - resource->Identifier(), this, response_, - resource); + probe::didReceiveResourceResponse( + probe::ToCoreProbeSink(frame_->GetDocument()), resource->Identifier(), + this, response_, resource); fetcher_->StopFetching(); return; } @@ -1097,7 +1106,7 @@ // Links with media values need more information (like viewport information). // This happens after the first chunk is parsed in HTMLDocumentParser. - DispatchLinkHeaderPreloads(nullptr, LinkLoader::kOnlyLoadNonMedia); + DispatchLinkHeaderPreloads(nullptr, PreloadHelper::kOnlyLoadNonMedia); frame_->GetPage()->DidCommitLoad(frame_); GetUseCounter().DidCommitLoad(frame_);
diff --git a/third_party/blink/renderer/core/loader/document_loader.h b/third_party/blink/renderer/core/loader/document_loader.h index db9eb80..a7202cd 100644 --- a/third_party/blink/renderer/core/loader/document_loader.h +++ b/third_party/blink/renderer/core/loader/document_loader.h
@@ -48,8 +48,8 @@ #include "third_party/blink/renderer/core/html/parser/parser_synchronization_policy.h" #include "third_party/blink/renderer/core/loader/document_load_timing.h" #include "third_party/blink/renderer/core/loader/frame_loader_types.h" -#include "third_party/blink/renderer/core/loader/link_loader.h" #include "third_party/blink/renderer/core/loader/navigation_policy.h" +#include "third_party/blink/renderer/core/loader/preload_helper.h" #include "third_party/blink/renderer/core/loader/previews_resource_loading_hints.h" #include "third_party/blink/renderer/core/page/viewport_description.h" #include "third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.h" @@ -108,9 +108,8 @@ const AtomicString& MimeType() const; - const ResourceRequest& OriginalRequest() const; - - const ResourceRequest& GetRequest() const; + const KURL& OriginalUrl() const; + const AtomicString& OriginalReferrer() const; ResourceFetcher* Fetcher() const { return fetcher_.Get(); } @@ -131,6 +130,8 @@ const KURL& Url() const; const KURL& UnreachableURL() const; const KURL& UrlForHistory() const; + const AtomicString& Referrer() const; + EncodedFormData* HttpBody() const; void DidChangePerformanceTiming(); void DidObserveLoadingBehavior(WebLoadingBehaviorFlag); @@ -208,7 +209,7 @@ bool WasBlockedAfterCSP() { return was_blocked_after_csp_; } void DispatchLinkHeaderPreloads(ViewportDescriptionWrapper*, - LinkLoader::MediaPreloadPolicy); + PreloadHelper::MediaPreloadPolicy); void SetServiceWorkerNetworkProvider( std::unique_ptr<WebServiceWorkerNetworkProvider>); @@ -273,6 +274,11 @@ Vector<KURL> redirect_chain_; + // The 'working' request. It may be mutated + // several times from the original request to include additional + // headers, cookie information, canonicalization and redirects. + ResourceRequest request_; + private: // installNewDocument() does the work of creating a Document and // DocumentParser, as well as creating a new LocalDOMWindow if needed. It also @@ -358,17 +364,12 @@ // Stores the resource loading hints for this document. Member<PreviewsResourceLoadingHints> resource_loading_hints_; - // A reference to actual request used to create the data source. - // The only part of this request that should change is the url, and - // that only in the case of a same-document navigation. - ResourceRequest original_request_; - SubstituteData substitute_data_; - // The 'working' request. It may be mutated - // several times from the original request to include additional - // headers, cookie information, canonicalization and redirects. - ResourceRequest request_; + // A reference to actual request's url and referrer used to + // inititate this load. + KURL original_url_; + AtomicString original_referrer_; ResourceResponse response_;
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.cc b/third_party/blink/renderer/core/loader/frame_fetch_context.cc index 6d126cd..e827c6d 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.cc +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
@@ -313,7 +313,7 @@ if (loader && context->GetSettings()->GetSavePreviousDocumentResources() != SavePreviousDocumentResources::kNever) { if (Document* previous_document = context->GetFrame()->GetDocument()) { - if (previous_document->IsSecureTransitionTo(loader->Url())) { + if (previous_document->IsSecureTransitionTo(NullURL())) { fetcher->HoldResourcesFromPreviousFetcher( previous_document->Loader()->Fetcher()); } @@ -640,17 +640,17 @@ MixedContentChecker::CheckMixedPrivatePublic(GetFrame(), response.RemoteIPAddress()); - LinkLoader::CanLoadResources resource_loading_policy = + PreloadHelper::CanLoadResources resource_loading_policy = response_type == ResourceResponseType::kFromMemoryCache - ? LinkLoader::kDoNotLoadResources - : LinkLoader::kLoadResourcesAndPreconnect; + ? PreloadHelper::kDoNotLoadResources + : PreloadHelper::kLoadResourcesAndPreconnect; if (document_loader_ && document_loader_ == document_loader_->GetFrame() ->Loader() .GetProvisionalDocumentLoader()) { // When response is received with a provisional docloader, the resource // haven't committed yet, and we cannot load resources, only preconnect. - resource_loading_policy = LinkLoader::kDoNotLoadResources; + resource_loading_policy = PreloadHelper::kDoNotLoadResources; } // Client hints preferences should be persisted only from responses that were // served by the same host as the host of the document-level origin. @@ -667,10 +667,10 @@ ParseAndPersistClientHints(response); } - LinkLoader::LoadLinksFromHeader( + PreloadHelper::LoadLinksFromHeader( response.HttpHeaderField(http_names::kLink), response.CurrentRequestUrl(), *GetFrame(), document_, NetworkHintsInterfaceImpl(), - resource_loading_policy, LinkLoader::kLoadAll, nullptr); + resource_loading_policy, PreloadHelper::kLoadAll, nullptr); if (response.HasMajorCertificateErrors()) { MixedContentChecker::HandleCertificateError(GetFrame(), response, @@ -694,8 +694,8 @@ GetFrame()->Loader().Progress().IncrementProgress(identifier, response); GetLocalFrameClient()->DispatchDidReceiveResponse(response); DocumentLoader* document_loader = MasterDocumentLoader(); - probe::didReceiveResourceResponse(GetFrame()->GetDocument(), identifier, - document_loader, response, resource); + probe::didReceiveResourceResponse(Probe(), identifier, document_loader, + response, resource); // It is essential that inspector gets resource response BEFORE console. GetFrame()->Console().ReportResourceResponseReceived(document_loader, identifier, response); @@ -708,8 +708,8 @@ return; GetFrame()->Loader().Progress().IncrementProgress(identifier, data_length); - probe::didReceiveData(GetFrame()->GetDocument(), identifier, - MasterDocumentLoader(), data, data_length); + probe::didReceiveData(Probe(), identifier, MasterDocumentLoader(), data, + data_length); } void FrameFetchContext::DispatchDidReceiveEncodedData( @@ -717,9 +717,8 @@ size_t encoded_data_length) { if (IsDetached()) return; - probe::didReceiveEncodedDataLength(GetFrame()->GetDocument(), - MasterDocumentLoader(), identifier, - encoded_data_length); + probe::didReceiveEncodedDataLength(Probe(), MasterDocumentLoader(), + identifier, encoded_data_length); } void FrameFetchContext::DispatchDidDownloadToBlob(unsigned long identifier, @@ -727,8 +726,7 @@ if (IsDetached() || !blob) return; - probe::didReceiveBlob(GetFrame()->GetDocument(), identifier, - MasterDocumentLoader(), blob); + probe::didReceiveBlob(Probe(), identifier, MasterDocumentLoader(), blob); } void FrameFetchContext::DispatchDidFinishLoading( @@ -741,9 +739,8 @@ return; GetFrame()->Loader().Progress().CompleteProgress(identifier); - probe::didFinishLoading(GetFrame()->GetDocument(), identifier, - MasterDocumentLoader(), finish_time, - encoded_data_length, decoded_body_length, + probe::didFinishLoading(Probe(), identifier, MasterDocumentLoader(), + finish_time, encoded_data_length, decoded_body_length, should_report_corb_blocking); if (document_) { InteractiveDetector* interactive_detector( @@ -778,8 +775,7 @@ } GetFrame()->Loader().Progress().CompleteProgress(identifier); - probe::didFailLoading(GetFrame()->GetDocument(), identifier, - MasterDocumentLoader(), error); + probe::didFailLoading(Probe(), identifier, MasterDocumentLoader(), error); if (document_) { InteractiveDetector* interactive_detector( InteractiveDetector::From(*document_)); @@ -1176,8 +1172,7 @@ if (IsDetached()) return false; bool should_block_request = false; - probe::shouldBlockRequest(GetFrame()->GetDocument(), url, - &should_block_request); + probe::shouldBlockRequest(Probe(), url, &should_block_request); return should_block_request; } @@ -1589,4 +1584,8 @@ reporting_policy, redirect_status); } +CoreProbeSink* FrameFetchContext::Probe() const { + return probe::ToCoreProbeSink(GetFrame()->GetDocument()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.h b/third_party/blink/renderer/core/loader/frame_fetch_context.h index 9aed599d..ce825ee 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.h +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.h
@@ -51,6 +51,7 @@ namespace blink { class ClientHintsPreferences; +class CoreProbeSink; class Document; class DocumentLoader; class LocalFrame; @@ -267,6 +268,8 @@ // Returns the origin of the top frame in the document. scoped_refptr<const SecurityOrigin> GetTopFrameOrigin() const; + CoreProbeSink* Probe() const; + Member<DocumentLoader> document_loader_; Member<Document> document_;
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index f3992de..697a18b 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -78,7 +78,6 @@ #include "third_party/blink/renderer/core/loader/document_loader.h" #include "third_party/blink/renderer/core/loader/form_submission.h" #include "third_party/blink/renderer/core/loader/frame_load_request.h" -#include "third_party/blink/renderer/core/loader/link_loader.h" #include "third_party/blink/renderer/core/loader/mixed_content_checker.h" #include "third_party/blink/renderer/core/loader/navigation_scheduler.h" #include "third_party/blink/renderer/core/loader/network_hints_interface.h" @@ -712,8 +711,29 @@ return true; KURL url = request.GetResourceRequest().Url(); - if (frame_->GetScriptController().ExecuteScriptIfJavaScriptURL(url, nullptr)) - return false; + if (url.ProtocolIsJavaScript()) { + Document* origin_document = request.OriginDocument(); + // Check the CSP of the caller (the "source browsing context") if required, + // as per https://html.spec.whatwg.org/#javascript-protocol. + bool javascript_url_is_allowed = + request.ShouldCheckMainWorldContentSecurityPolicy() == + kDoNotCheckContentSecurityPolicy || + origin_document->GetContentSecurityPolicy()->AllowJavaScriptURLs( + frame_->DeprecatedLocalOwner(), url.GetString(), + origin_document->Url(), OrdinalNumber::First()); + + if (!javascript_url_is_allowed) + return false; + + if (frame_->Owner() && frame_->Owner()->GetSandboxFlags() & kSandboxOrigin) + return false; + + if (frame_->GetScriptController().ExecuteScriptIfJavaScriptURL( + url, nullptr, + request.ShouldCheckMainWorldContentSecurityPolicy())) { + return false; + } + } if (!request.OriginDocument()->GetSecurityOrigin()->CanDisplay(url)) { request.OriginDocument()->AddConsoleMessage(ConsoleMessage::Create( @@ -1375,7 +1395,8 @@ String FrameLoader::UserAgent() const { String user_agent = Client()->UserAgent(); - probe::applyUserAgentOverride(frame_->GetDocument(), &user_agent); + probe::applyUserAgentOverride(probe::ToCoreProbeSink(frame_->GetDocument()), + &user_agent); return user_agent; }
diff --git a/third_party/blink/renderer/core/loader/link_load_parameters.cc b/third_party/blink/renderer/core/loader/link_load_parameters.cc new file mode 100644 index 0000000..0bc29e5 --- /dev/null +++ b/third_party/blink/renderer/core/loader/link_load_parameters.cc
@@ -0,0 +1,56 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/loader/link_load_parameters.h" + +#include "third_party/blink/renderer/platform/loader/link_header.h" + +namespace blink { + +LinkLoadParameters::LinkLoadParameters( + const LinkRelAttribute& rel, + const CrossOriginAttributeValue& cross_origin, + const String& type, + const String& as, + const String& media, + const String& nonce, + const String& integrity, + const String& importance, + network::mojom::ReferrerPolicy referrer_policy, + const KURL& href, + const String& image_srcset, + const String& image_sizes) + : rel(rel), + cross_origin(cross_origin), + type(type), + as(as), + media(media), + nonce(nonce), + integrity(integrity), + importance(importance), + referrer_policy(referrer_policy), + href(href), + image_srcset(image_srcset), + image_sizes(image_sizes) {} + +// TODO(domfarolino) +// Eventually we'll want to support an |importance| value on +// LinkHeaders. We can communicate a header's importance value +// to LinkLoadParameters here, likely after modifying the LinkHeader +// class. See https://crbug.com/821464 for info on Priority Hints. +LinkLoadParameters::LinkLoadParameters(const LinkHeader& header, + const KURL& base_url) + : rel(LinkRelAttribute(header.Rel())), + cross_origin(GetCrossOriginAttributeValue(header.CrossOrigin())), + type(header.MimeType()), + as(header.As()), + media(header.Media()), + nonce(header.Nonce()), + integrity(header.Integrity()), + referrer_policy(network::mojom::ReferrerPolicy::kDefault), + href(KURL(base_url, header.Url())), + image_srcset(header.ImageSrcset()), + image_sizes(header.ImageSizes()) {} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/loader/link_load_parameters.h b/third_party/blink/renderer/core/loader/link_load_parameters.h new file mode 100644 index 0000000..d64c125 --- /dev/null +++ b/third_party/blink/renderer/core/loader/link_load_parameters.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 THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_LINK_LOAD_PARAMETERS_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_LINK_LOAD_PARAMETERS_H_ + +#include "services/network/public/mojom/referrer_policy.mojom-shared.h" +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/html/cross_origin_attribute.h" +#include "third_party/blink/renderer/core/html/link_rel_attribute.h" +#include "third_party/blink/renderer/platform/weborigin/kurl.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +class LinkHeader; + +struct CORE_EXPORT LinkLoadParameters { + LinkLoadParameters(const LinkRelAttribute&, + const CrossOriginAttributeValue&, + const String& type, + const String& as, + const String& media, + const String& nonce, + const String& integrity, + const String& importance, + network::mojom::ReferrerPolicy, + const KURL& href, + const String& image_srcset, + const String& image_sizes); + LinkLoadParameters(const LinkHeader&, const KURL& base_url); + + LinkRelAttribute rel; + CrossOriginAttributeValue cross_origin; + String type; + String as; + String media; + String nonce; + String integrity; + String importance; + network::mojom::ReferrerPolicy referrer_policy; + KURL href; + String image_srcset; + String image_sizes; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_LINK_LOAD_PARAMETERS_H_
diff --git a/third_party/blink/renderer/core/loader/link_loader.cc b/third_party/blink/renderer/core/loader/link_loader.cc index 3b99308..46d5b1e5 100644 --- a/third_party/blink/renderer/core/loader/link_loader.cc +++ b/third_party/blink/renderer/core/loader/link_loader.cc
@@ -32,48 +32,29 @@ #include "third_party/blink/renderer/core/loader/link_loader.h" #include "third_party/blink/public/platform/web_prerender.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" -#include "third_party/blink/renderer/core/css/media_list.h" -#include "third_party/blink/renderer/core/css/media_query_evaluator.h" -#include "third_party/blink/renderer/core/css/parser/sizes_attribute_parser.h" #include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/frame/frame_console.h" #include "third_party/blink/renderer/core/frame/local_frame.h" -#include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/frame/use_counter.h" -#include "third_party/blink/renderer/core/frame/viewport_data.h" -#include "third_party/blink/renderer/core/html/cross_origin_attribute.h" -#include "third_party/blink/renderer/core/html/link_rel_attribute.h" -#include "third_party/blink/renderer/core/html/parser/html_preload_scanner.h" -#include "third_party/blink/renderer/core/html/parser/html_srcset_parser.h" -#include "third_party/blink/renderer/core/inspector/console_message.h" -#include "third_party/blink/renderer/core/loader/document_loader.h" #include "third_party/blink/renderer/core/loader/importance_attribute.h" -#include "third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h" -#include "third_party/blink/renderer/core/loader/network_hints_interface.h" +#include "third_party/blink/renderer/core/loader/link_load_parameters.h" +#include "third_party/blink/renderer/core/loader/link_loader_client.h" +#include "third_party/blink/renderer/core/loader/preload_helper.h" #include "third_party/blink/renderer/core/loader/private/prerender_handle.h" #include "third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h" -#include "third_party/blink/renderer/core/loader/resource/font_resource.h" -#include "third_party/blink/renderer/core/loader/resource/image_resource.h" -#include "third_party/blink/renderer/core/loader/resource/link_fetch_resource.h" -#include "third_party/blink/renderer/core/loader/resource/script_resource.h" #include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h" -#include "third_party/blink/renderer/core/script/module_script.h" -#include "third_party/blink/renderer/core/script/script_loader.h" -#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h" -#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_client.h" -#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_finish_observer.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h" -#include "third_party/blink/renderer/platform/loader/link_header.h" #include "third_party/blink/renderer/platform/loader/subresource_integrity.h" -#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h" #include "third_party/blink/renderer/platform/prerender.h" namespace blink { -static unsigned PrerenderRelTypesFromRelAttribute( +class NetworkHintsInterface; + +namespace { + +unsigned PrerenderRelTypesFromRelAttribute( const LinkRelAttribute& rel_attribute, Document& document) { unsigned result = 0; @@ -89,24 +70,12 @@ return result; } -// TODO(domfarolino) -// Eventually we'll want to support an |importance| value on -// LinkHeaders. We can communicate a header's importance value -// to LinkLoadParameters here, likely after modifying the LinkHeader -// class. See https://crbug.com/821464 for info on Priority Hints. -LinkLoadParameters::LinkLoadParameters(const LinkHeader& header, - const KURL& base_url) - : rel(LinkRelAttribute(header.Rel())), - cross_origin(GetCrossOriginAttributeValue(header.CrossOrigin())), - type(header.MimeType()), - as(header.As()), - media(header.Media()), - nonce(header.Nonce()), - integrity(header.Integrity()), - referrer_policy(network::mojom::ReferrerPolicy::kDefault), - href(KURL(base_url, header.Url())), - image_srcset(header.ImageSrcset()), - image_sizes(header.ImageSizes()) {} +} // namespace + +LinkLoader* LinkLoader::Create(LinkLoaderClient* client) { + return MakeGarbageCollected<LinkLoader>(client, + client->GetLoadingTaskRunner()); +} class LinkLoader::FinishObserver final : public GarbageCollectedFinalized<ResourceFinishObserver>, @@ -195,496 +164,10 @@ client_->DidSendDOMContentLoadedForLinkPrerender(); } -enum LinkCaller { - kLinkCalledFromHeader, - kLinkCalledFromMarkup, -}; - -static void SendMessageToConsoleForPossiblyNullDocument( - ConsoleMessage* console_message, - Document* document, - LocalFrame* frame) { - DCHECK(document || frame); - DCHECK(!document || document->GetFrame() == frame); - // Route the console message through Document if possible, so that script line - // numbers can be included. Otherwise, route directly to the FrameConsole, to - // ensure we never drop a message. - if (document) - document->AddConsoleMessage(console_message); - else - frame->Console().AddMessage(console_message); -} - -static void DnsPrefetchIfNeeded( - const LinkLoadParameters& params, - Document* document, - LocalFrame* frame, - const NetworkHintsInterface& network_hints_interface, - LinkCaller caller) { - if (params.rel.IsDNSPrefetch()) { - UseCounter::Count(frame, WebFeature::kLinkRelDnsPrefetch); - if (caller == kLinkCalledFromHeader) - UseCounter::Count(frame, WebFeature::kLinkHeaderDnsPrefetch); - Settings* settings = frame ? frame->GetSettings() : nullptr; - // FIXME: The href attribute of the link element can be in "//hostname" - // form, and we shouldn't attempt to complete that as URL - // <https://bugs.webkit.org/show_bug.cgi?id=48857>. - if (settings && settings->GetDNSPrefetchingEnabled() && - params.href.IsValid() && !params.href.IsEmpty()) { - if (settings->GetLogDnsPrefetchAndPreconnect()) { - SendMessageToConsoleForPossiblyNullDocument( - ConsoleMessage::Create( - kOtherMessageSource, kVerboseMessageLevel, - String("DNS prefetch triggered for " + params.href.Host())), - document, frame); - } - network_hints_interface.DnsPrefetchHost(params.href.Host()); - } - } -} - -static void PreconnectIfNeeded( - const LinkLoadParameters& params, - Document* document, - LocalFrame* frame, - const NetworkHintsInterface& network_hints_interface, - LinkCaller caller) { - if (params.rel.IsPreconnect() && params.href.IsValid() && - params.href.ProtocolIsInHTTPFamily()) { - UseCounter::Count(frame, WebFeature::kLinkRelPreconnect); - if (caller == kLinkCalledFromHeader) - UseCounter::Count(frame, WebFeature::kLinkHeaderPreconnect); - Settings* settings = frame ? frame->GetSettings() : nullptr; - if (settings && settings->GetLogDnsPrefetchAndPreconnect()) { - SendMessageToConsoleForPossiblyNullDocument( - ConsoleMessage::Create( - kOtherMessageSource, kVerboseMessageLevel, - String("Preconnect triggered for ") + params.href.GetString()), - document, frame); - if (params.cross_origin != kCrossOriginAttributeNotSet) { - SendMessageToConsoleForPossiblyNullDocument( - ConsoleMessage::Create(kOtherMessageSource, kVerboseMessageLevel, - String("Preconnect CORS setting is ") + - String((params.cross_origin == - kCrossOriginAttributeAnonymous) - ? "anonymous" - : "use-credentials")), - document, frame); - } - } - network_hints_interface.PreconnectHost(params.href, params.cross_origin); - } -} - -base::Optional<ResourceType> LinkLoader::GetResourceTypeFromAsAttribute( - const String& as) { - DCHECK_EQ(as.DeprecatedLower(), as); - if (as == "image") { - return ResourceType::kImage; - } else if (as == "script") { - return ResourceType::kScript; - } else if (as == "style") { - return ResourceType::kCSSStyleSheet; - } else if (as == "video") { - return ResourceType::kVideo; - } else if (as == "audio") { - return ResourceType::kAudio; - } else if (as == "track") { - return ResourceType::kTextTrack; - } else if (as == "font") { - return ResourceType::kFont; - } else if (as == "fetch") { - return ResourceType::kRaw; - } - return base::nullopt; -} - Resource* LinkLoader::GetResourceForTesting() { return finish_observer_ ? finish_observer_->GetResource() : nullptr; } -static bool IsSupportedType(ResourceType resource_type, - const String& mime_type) { - if (mime_type.IsEmpty()) - return true; - switch (resource_type) { - case ResourceType::kImage: - return MIMETypeRegistry::IsSupportedImagePrefixedMIMEType(mime_type); - case ResourceType::kScript: - return MIMETypeRegistry::IsSupportedJavaScriptMIMEType(mime_type); - case ResourceType::kCSSStyleSheet: - return MIMETypeRegistry::IsSupportedStyleSheetMIMEType(mime_type); - case ResourceType::kFont: - return MIMETypeRegistry::IsSupportedFontMIMEType(mime_type); - case ResourceType::kAudio: - case ResourceType::kVideo: - return MIMETypeRegistry::IsSupportedMediaMIMEType(mime_type, String()); - case ResourceType::kTextTrack: - return MIMETypeRegistry::IsSupportedTextTrackMIMEType(mime_type); - case ResourceType::kRaw: - return true; - default: - NOTREACHED(); - } - return false; -} - -static MediaValues* CreateMediaValues( - Document& document, - ViewportDescription* viewport_description) { - MediaValues* media_values = - MediaValues::CreateDynamicIfFrameExists(document.GetFrame()); - if (viewport_description) { - FloatSize initial_viewport(media_values->DeviceWidth(), - media_values->DeviceHeight()); - PageScaleConstraints constraints = viewport_description->Resolve( - initial_viewport, document.GetViewportData().ViewportDefaultMinWidth()); - media_values->OverrideViewportDimensions(constraints.layout_size.Width(), - constraints.layout_size.Height()); - } - return media_values; -} - -static bool MediaMatches(const String& media, MediaValues* media_values) { - scoped_refptr<MediaQuerySet> media_queries = MediaQuerySet::Create(media); - MediaQueryEvaluator evaluator(*media_values); - return evaluator.Eval(*media_queries); -} - -// |base_url| is used in Link HTTP Header based preloads to resolve relative -// URLs in srcset, which should be based on the resource's URL, not the -// document's base URL. If |base_url| is a null URL, relative URLs are resolved -// using |document.CompleteURL()|. -static Resource* PreloadIfNeeded(const LinkLoadParameters& params, - Document& document, - const KURL& base_url, - LinkCaller caller, - ViewportDescription* viewport_description, - ParserDisposition parser_disposition) { - if (!document.Loader() || !params.rel.IsLinkPreload()) - return nullptr; - - base::Optional<ResourceType> resource_type = - LinkLoader::GetResourceTypeFromAsAttribute(params.as); - - MediaValues* media_values = nullptr; - KURL url; - if (resource_type == ResourceType::kImage && !params.image_srcset.IsEmpty() && - RuntimeEnabledFeatures::PreloadImageSrcSetEnabled()) { - media_values = CreateMediaValues(document, viewport_description); - float source_size = - SizesAttributeParser(media_values, params.image_sizes).length(); - ImageCandidate candidate = BestFitSourceForImageAttributes( - media_values->DevicePixelRatio(), source_size, params.href, - params.image_srcset); - url = base_url.IsNull() ? document.CompleteURL(candidate.ToString()) - : KURL(base_url, candidate.ToString()); - } else { - url = params.href; - } - - UseCounter::Count(document, WebFeature::kLinkRelPreload); - if (!url.IsValid() || url.IsEmpty()) { - document.AddConsoleMessage(ConsoleMessage::Create( - kOtherMessageSource, kWarningMessageLevel, - String("<link rel=preload> has an invalid `href` value"))); - return nullptr; - } - - // Preload only if media matches - if (!params.media.IsEmpty()) { - if (!media_values) - media_values = CreateMediaValues(document, viewport_description); - if (!MediaMatches(params.media, media_values)) - return nullptr; - } - - if (caller == kLinkCalledFromHeader) - UseCounter::Count(document, WebFeature::kLinkHeaderPreload); - if (resource_type == base::nullopt) { - document.AddConsoleMessage(ConsoleMessage::Create( - kOtherMessageSource, kWarningMessageLevel, - String("<link rel=preload> must have a valid `as` value"))); - return nullptr; - } - - if (!IsSupportedType(resource_type.value(), params.type)) { - document.AddConsoleMessage(ConsoleMessage::Create( - kOtherMessageSource, kWarningMessageLevel, - String("<link rel=preload> has an unsupported `type` value"))); - return nullptr; - } - ResourceRequest resource_request(url); - resource_request.SetRequestContext(ResourceFetcher::DetermineRequestContext( - resource_type.value(), ResourceFetcher::kImageNotImageSet, false)); - - resource_request.SetReferrerPolicy(params.referrer_policy); - - resource_request.SetFetchImportanceMode( - GetFetchImportanceAttributeValue(params.importance)); - - ResourceLoaderOptions options; - options.initiator_info.name = fetch_initiator_type_names::kLink; - options.parser_disposition = parser_disposition; - FetchParameters link_fetch_params(resource_request, options); - link_fetch_params.SetCharset(document.Encoding()); - - if (params.cross_origin != kCrossOriginAttributeNotSet) { - link_fetch_params.SetCrossOriginAccessControl(document.GetSecurityOrigin(), - params.cross_origin); - } - link_fetch_params.SetContentSecurityPolicyNonce(params.nonce); - Settings* settings = document.GetSettings(); - if (settings && settings->GetLogPreload()) { - document.AddConsoleMessage(ConsoleMessage::Create( - kOtherMessageSource, kVerboseMessageLevel, - String("Preload triggered for " + url.Host() + url.GetPath()))); - } - link_fetch_params.SetLinkPreload(true); - return LinkLoader::StartPreload(resource_type.value(), link_fetch_params, - document.Fetcher()); -} - -// https://html.spec.whatwg.org/multipage/links.html#link-type-modulepreload -static void ModulePreloadIfNeeded(const LinkLoadParameters& params, - Document& document, - ViewportDescription* viewport_description, - LinkLoader* link_loader) { - if (!document.Loader() || !params.rel.IsModulePreload()) - return; - - UseCounter::Count(document, WebFeature::kLinkRelModulePreload); - - // Step 1. "If the href attribute's value is the empty string, then return." - // [spec text] - if (params.href.IsEmpty()) { - document.AddConsoleMessage( - ConsoleMessage::Create(kOtherMessageSource, kWarningMessageLevel, - "<link rel=modulepreload> has no `href` value")); - return; - } - - // Step 2. "Let destination be the current state of the as attribute (a - // destination), or "script" if it is in no state." [spec text] - // Step 3. "If destination is not script-like, then queue a task on the - // networking task source to fire an event named error at the link element, - // and return." [spec text] - // Currently we only support as="script". - if (!params.as.IsEmpty() && params.as != "script") { - document.AddConsoleMessage(ConsoleMessage::Create( - kOtherMessageSource, kWarningMessageLevel, - String("<link rel=modulepreload> has an invalid `as` value " + - params.as))); - if (link_loader) - link_loader->DispatchLinkLoadingErroredAsync(); - return; - } - mojom::RequestContextType destination = mojom::RequestContextType::SCRIPT; - - // Step 4. "Parse the URL given by the href attribute, relative to the - // element's node document. If that fails, then return. Otherwise, let url be - // the resulting URL record." [spec text] - // |href| is already resolved in caller side. - if (!params.href.IsValid()) { - document.AddConsoleMessage(ConsoleMessage::Create( - kOtherMessageSource, kWarningMessageLevel, - "<link rel=modulepreload> has an invalid `href` value " + - params.href.GetString())); - return; - } - - // Preload only if media matches. - // https://html.spec.whatwg.org/#processing-the-media-attribute - if (!params.media.IsEmpty()) { - MediaValues* media_values = - CreateMediaValues(document, viewport_description); - if (!MediaMatches(params.media, media_values)) - return; - } - - // Step 5. "Let settings object be the link element's node document's relevant - // settings object." [spec text] - // |document| is the node document here, and its context document is the - // relevant settings object. - Document* context_document = document.ContextDocument(); - Modulator* modulator = - Modulator::From(ToScriptStateForMainWorld(context_document->GetFrame())); - DCHECK(modulator); - if (!modulator) - return; - - // Step 6. "Let credentials mode be the module script credentials mode for the - // crossorigin attribute." [spec text] - network::mojom::FetchCredentialsMode credentials_mode = - ScriptLoader::ModuleScriptCredentialsMode(params.cross_origin); - - // Step 7. "Let cryptographic nonce be the value of the nonce attribute, if it - // is specified, or the empty string otherwise." [spec text] - // |nonce| parameter is the value of the nonce attribute. - - // Step 8. "Let integrity metadata be the value of the integrity attribute, if - // it is specified, or the empty string otherwise." [spec text] - IntegrityMetadataSet integrity_metadata; - if (!params.integrity.IsEmpty()) { - SubresourceIntegrity::IntegrityFeatures integrity_features = - SubresourceIntegrityHelper::GetFeatures(&document); - SubresourceIntegrity::ReportInfo report_info; - SubresourceIntegrity::ParseIntegrityAttribute( - params.integrity, integrity_features, integrity_metadata, &report_info); - SubresourceIntegrityHelper::DoReport(document, report_info); - } - - // Step 9. "Let referrer policy be the current state of the element's - // referrerpolicy attribute." [spec text] - // |referrer_policy| parameter is the value of the referrerpolicy attribute. - - // Step 10. "Let options be a script fetch options whose cryptographic nonce - // is cryptographic nonce, integrity metadata is integrity metadata, parser - // metadata is "not-parser-inserted", credentials mode is credentials mode, - // and referrer policy is referrer policy." [spec text] - ModuleScriptFetchRequest request( - params.href, destination, - ScriptFetchOptions(params.nonce, integrity_metadata, params.integrity, - kNotParserInserted, credentials_mode, - params.referrer_policy), - Referrer::NoReferrer(), TextPosition::MinimumPosition()); - - // Step 11. "Fetch a single module script given url, settings object, - // destination, options, settings object, "client", and with the top-level - // module fetch flag set. Wait until algorithm asynchronously completes with - // result." [spec text] - modulator->FetchSingle(request, context_document->Fetcher(), - ModuleGraphLevel::kDependentModuleFetch, - ModuleScriptCustomFetchType::kNone, link_loader); - - Settings* settings = document.GetSettings(); - if (settings && settings->GetLogPreload()) { - document.AddConsoleMessage( - ConsoleMessage::Create(kOtherMessageSource, kVerboseMessageLevel, - "Module preload triggered for " + - params.href.Host() + params.href.GetPath())); - } - - // Asynchronously continue processing after - // LinkLoader::NotifyModuleLoadFinished() is called. -} - -static Resource* PrefetchIfNeeded(const LinkLoadParameters& params, - Document& document) { - if (params.rel.IsLinkPrefetch() && params.href.IsValid() && - document.GetFrame()) { - UseCounter::Count(document, WebFeature::kLinkRelPrefetch); - - ResourceRequest resource_request(params.href); - resource_request.SetReferrerPolicy(params.referrer_policy); - resource_request.SetFetchImportanceMode( - GetFetchImportanceAttributeValue(params.importance)); - - ResourceLoaderOptions options; - options.initiator_info.name = fetch_initiator_type_names::kLink; - - FetchParameters link_fetch_params(resource_request, options); - if (params.cross_origin != kCrossOriginAttributeNotSet) { - link_fetch_params.SetCrossOriginAccessControl( - document.GetSecurityOrigin(), params.cross_origin); - } - return LinkFetchResource::Fetch(ResourceType::kLinkPrefetch, - link_fetch_params, document.Fetcher()); - } - return nullptr; -} - -void LinkLoader::LoadLinksFromHeader( - const String& header_value, - const KURL& base_url, - LocalFrame& frame, - Document* document, - const NetworkHintsInterface& network_hints_interface, - CanLoadResources can_load_resources, - MediaPreloadPolicy media_policy, - ViewportDescriptionWrapper* viewport_description_wrapper) { - if (header_value.IsEmpty()) - return; - LinkHeaderSet header_set(header_value); - for (auto& header : header_set) { - if (!header.Valid() || header.Url().IsEmpty() || header.Rel().IsEmpty()) - continue; - - if (media_policy == kOnlyLoadMedia && !header.IsViewportDependent()) - continue; - if (media_policy == kOnlyLoadNonMedia && header.IsViewportDependent()) - continue; - - const LinkLoadParameters params(header, base_url); - // Sanity check to avoid re-entrancy here. - if (params.href == base_url) - continue; - if (can_load_resources != kOnlyLoadResources) { - DnsPrefetchIfNeeded(params, document, &frame, network_hints_interface, - kLinkCalledFromHeader); - - PreconnectIfNeeded(params, document, &frame, network_hints_interface, - kLinkCalledFromHeader); - } - if (can_load_resources != kDoNotLoadResources) { - DCHECK(document); - ViewportDescription* viewport_description = - (viewport_description_wrapper && viewport_description_wrapper->set) - ? &(viewport_description_wrapper->description) - : nullptr; - - PreloadIfNeeded(params, *document, base_url, kLinkCalledFromHeader, - viewport_description, kNotParserInserted); - PrefetchIfNeeded(params, *document); - ModulePreloadIfNeeded(params, *document, viewport_description, nullptr); - } - if (params.rel.IsServiceWorker()) { - UseCounter::Count(&frame, WebFeature::kLinkHeaderServiceWorker); - } - // TODO(yoav): Add more supported headers as needed. - } -} - -Resource* LinkLoader::StartPreload(ResourceType type, - FetchParameters& params, - ResourceFetcher* resource_fetcher) { - Resource* resource = nullptr; - switch (type) { - case ResourceType::kImage: - resource = ImageResource::Fetch(params, resource_fetcher); - break; - case ResourceType::kScript: - params.SetRequestContext(mojom::RequestContextType::SCRIPT); - resource = ScriptResource::Fetch(params, resource_fetcher, nullptr, - ScriptResource::kAllowStreaming); - break; - case ResourceType::kCSSStyleSheet: - resource = - CSSStyleSheetResource::Fetch(params, resource_fetcher, nullptr); - break; - case ResourceType::kFont: - resource = FontResource::Fetch(params, resource_fetcher, nullptr); - break; - case ResourceType::kAudio: - case ResourceType::kVideo: - resource = RawResource::FetchMedia(params, resource_fetcher, nullptr); - break; - case ResourceType::kTextTrack: - resource = RawResource::FetchTextTrack(params, resource_fetcher, nullptr); - break; - case ResourceType::kImportResource: - resource = RawResource::FetchImport(params, resource_fetcher, nullptr); - break; - case ResourceType::kRaw: - resource = RawResource::Fetch(params, resource_fetcher, nullptr); - break; - default: - NOTREACHED(); - } - - return resource; -} - bool LinkLoader::LoadLink( const LinkLoadParameters& params, Document& document, @@ -695,22 +178,25 @@ if (!client_->ShouldLoadLink()) return false; - DnsPrefetchIfNeeded(params, &document, document.GetFrame(), - network_hints_interface, kLinkCalledFromMarkup); + PreloadHelper::DnsPrefetchIfNeeded(params, &document, document.GetFrame(), + network_hints_interface, + PreloadHelper::kLinkCalledFromMarkup); - PreconnectIfNeeded(params, &document, document.GetFrame(), - network_hints_interface, kLinkCalledFromMarkup); + PreloadHelper::PreconnectIfNeeded(params, &document, document.GetFrame(), + network_hints_interface, + PreloadHelper::kLinkCalledFromMarkup); - Resource* resource = PreloadIfNeeded( - params, document, NullURL(), kLinkCalledFromMarkup, nullptr, + Resource* resource = PreloadHelper::PreloadIfNeeded( + params, document, NullURL(), PreloadHelper::kLinkCalledFromMarkup, + nullptr, client_->IsLinkCreatedByParser() ? kParserInserted : kNotParserInserted); if (!resource) { - resource = PrefetchIfNeeded(params, document); + resource = PreloadHelper::PrefetchIfNeeded(params, document); } if (resource) finish_observer_ = MakeGarbageCollected<FinishObserver>(this, resource); - ModulePreloadIfNeeded(params, document, nullptr, this); + PreloadHelper::ModulePreloadIfNeeded(params, document, nullptr, this); if (const unsigned prerender_rel_types = PrerenderRelTypesFromRelAttribute(params.rel, document)) { @@ -775,12 +261,6 @@ link_client); } -void LinkLoader::DispatchLinkLoadingErroredAsync() { - client_->GetLoadingTaskRunner()->PostTask( - FROM_HERE, WTF::Bind(&LinkLoaderClient::LinkLoadingErrored, - WrapPersistent(client_.Get()))); -} - void LinkLoader::Abort() { if (prerender_) { prerender_->Cancel();
diff --git a/third_party/blink/renderer/core/loader/link_loader.h b/third_party/blink/renderer/core/loader/link_loader.h index 6eca21d1..dc9f1eb7 100644 --- a/third_party/blink/renderer/core/loader/link_loader.h +++ b/third_party/blink/renderer/core/loader/link_loader.h
@@ -32,68 +32,20 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_LINK_LOADER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_LINK_LOADER_H_ -#include "base/optional.h" #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/html/link_rel_attribute.h" -#include "third_party/blink/renderer/core/loader/link_loader_client.h" +#include "third_party/blink/renderer/core/loader/link_load_parameters.h" #include "third_party/blink/renderer/core/script/modulator.h" -#include "third_party/blink/renderer/platform/cross_origin_attribute_value.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h" -#include "third_party/blink/renderer/platform/loader/fetch/resource.h" #include "third_party/blink/renderer/platform/prerender_client.h" namespace blink { class Document; -class LinkHeader; -class LocalFrame; +class LinkLoaderClient; class NetworkHintsInterface; class PrerenderHandle; class Resource; -enum class ResourceType : uint8_t; -struct ViewportDescriptionWrapper; - -// The parameter object for LinkLoader::LoadLink(). -struct LinkLoadParameters { - LinkLoadParameters(const LinkRelAttribute& rel, - const CrossOriginAttributeValue& cross_origin, - const String& type, - const String& as, - const String& media, - const String& nonce, - const String& integrity, - const String& importance, - network::mojom::ReferrerPolicy referrer_policy, - const KURL& href, - const String& image_srcset, - const String& image_sizes) - : rel(rel), - cross_origin(cross_origin), - type(type), - as(as), - media(media), - nonce(nonce), - integrity(integrity), - importance(importance), - referrer_policy(referrer_policy), - href(href), - image_srcset(image_srcset), - image_sizes(image_sizes) {} - LinkLoadParameters(const LinkHeader&, const KURL& base_url); - - LinkRelAttribute rel; - CrossOriginAttributeValue cross_origin; - String type; - String as; - String media; - String nonce; - String integrity; - String importance; - network::mojom::ReferrerPolicy referrer_policy; - KURL href; - String image_srcset; - String image_sizes; -}; +class ResourceClient; // The LinkLoader can load link rel types icon, dns-prefetch, prefetch, and // prerender. @@ -102,10 +54,7 @@ USING_GARBAGE_COLLECTED_MIXIN(LinkLoader); public: - static LinkLoader* Create(LinkLoaderClient* client) { - return MakeGarbageCollected<LinkLoader>(client, - client->GetLoadingTaskRunner()); - } + static LinkLoader* Create(LinkLoaderClient*); LinkLoader(LinkLoaderClient*, scoped_refptr<base::SingleThreadTaskRunner>); ~LinkLoader() override; @@ -126,29 +75,6 @@ FetchParameters::DeferOption, Document&, ResourceClient*); - void DispatchLinkLoadingErroredAsync(); - - enum CanLoadResources { - kOnlyLoadResources, - kDoNotLoadResources, - kLoadResourcesAndPreconnect - }; - // Media links cannot be preloaded until the first chunk is parsed. The rest - // can be preloaded at commit time. - enum MediaPreloadPolicy { kLoadAll, kOnlyLoadNonMedia, kOnlyLoadMedia }; - static void LoadLinksFromHeader(const String& header_value, - const KURL& base_url, - LocalFrame&, - Document*, // can be nullptr - const NetworkHintsInterface&, - CanLoadResources, - MediaPreloadPolicy, - ViewportDescriptionWrapper*); - static Resource* StartPreload(ResourceType, - FetchParameters&, - ResourceFetcher*); - static base::Optional<ResourceType> GetResourceTypeFromAsAttribute( - const String& as); Resource* GetResourceForTesting();
diff --git a/third_party/blink/renderer/core/loader/preload_helper.cc b/third_party/blink/renderer/core/loader/preload_helper.cc new file mode 100644 index 0000000..89dbdcd --- /dev/null +++ b/third_party/blink/renderer/core/loader/preload_helper.cc
@@ -0,0 +1,531 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/loader/preload_helper.h" + +#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" +#include "third_party/blink/renderer/core/css/media_list.h" +#include "third_party/blink/renderer/core/css/media_query_evaluator.h" +#include "third_party/blink/renderer/core/css/parser/sizes_attribute_parser.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/frame/frame_console.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/frame/settings.h" +#include "third_party/blink/renderer/core/frame/use_counter.h" +#include "third_party/blink/renderer/core/frame/viewport_data.h" +#include "third_party/blink/renderer/core/html/parser/html_preload_scanner.h" +#include "third_party/blink/renderer/core/html/parser/html_srcset_parser.h" +#include "third_party/blink/renderer/core/inspector/console_message.h" +#include "third_party/blink/renderer/core/loader/importance_attribute.h" +#include "third_party/blink/renderer/core/loader/link_load_parameters.h" +#include "third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h" +#include "third_party/blink/renderer/core/loader/network_hints_interface.h" +#include "third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h" +#include "third_party/blink/renderer/core/loader/resource/font_resource.h" +#include "third_party/blink/renderer/core/loader/resource/image_resource.h" +#include "third_party/blink/renderer/core/loader/resource/link_fetch_resource.h" +#include "third_party/blink/renderer/core/loader/resource/script_resource.h" +#include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h" +#include "third_party/blink/renderer/core/script/modulator.h" +#include "third_party/blink/renderer/core/script/script_loader.h" +#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h" +#include "third_party/blink/renderer/platform/loader/fetch/raw_resource.h" +#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" +#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h" +#include "third_party/blink/renderer/platform/loader/link_header.h" +#include "third_party/blink/renderer/platform/loader/subresource_integrity.h" +#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h" + +namespace blink { + +namespace { + +void SendMessageToConsoleForPossiblyNullDocument( + ConsoleMessage* console_message, + Document* document, + LocalFrame* frame) { + DCHECK(document || frame); + DCHECK(!document || document->GetFrame() == frame); + // Route the console message through Document if possible, so that script line + // numbers can be included. Otherwise, route directly to the FrameConsole, to + // ensure we never drop a message. + if (document) + document->AddConsoleMessage(console_message); + else + frame->Console().AddMessage(console_message); +} + +bool IsSupportedType(ResourceType resource_type, const String& mime_type) { + if (mime_type.IsEmpty()) + return true; + switch (resource_type) { + case ResourceType::kImage: + return MIMETypeRegistry::IsSupportedImagePrefixedMIMEType(mime_type); + case ResourceType::kScript: + return MIMETypeRegistry::IsSupportedJavaScriptMIMEType(mime_type); + case ResourceType::kCSSStyleSheet: + return MIMETypeRegistry::IsSupportedStyleSheetMIMEType(mime_type); + case ResourceType::kFont: + return MIMETypeRegistry::IsSupportedFontMIMEType(mime_type); + case ResourceType::kAudio: + case ResourceType::kVideo: + return MIMETypeRegistry::IsSupportedMediaMIMEType(mime_type, String()); + case ResourceType::kTextTrack: + return MIMETypeRegistry::IsSupportedTextTrackMIMEType(mime_type); + case ResourceType::kRaw: + return true; + default: + NOTREACHED(); + } + return false; +} + +MediaValues* CreateMediaValues(Document& document, + ViewportDescription* viewport_description) { + MediaValues* media_values = + MediaValues::CreateDynamicIfFrameExists(document.GetFrame()); + if (viewport_description) { + FloatSize initial_viewport(media_values->DeviceWidth(), + media_values->DeviceHeight()); + PageScaleConstraints constraints = viewport_description->Resolve( + initial_viewport, document.GetViewportData().ViewportDefaultMinWidth()); + media_values->OverrideViewportDimensions(constraints.layout_size.Width(), + constraints.layout_size.Height()); + } + return media_values; +} + +} // namespace + +void PreloadHelper::DnsPrefetchIfNeeded( + const LinkLoadParameters& params, + Document* document, + LocalFrame* frame, + const NetworkHintsInterface& network_hints_interface, + LinkCaller caller) { + if (params.rel.IsDNSPrefetch()) { + UseCounter::Count(frame, WebFeature::kLinkRelDnsPrefetch); + if (caller == kLinkCalledFromHeader) + UseCounter::Count(frame, WebFeature::kLinkHeaderDnsPrefetch); + Settings* settings = frame ? frame->GetSettings() : nullptr; + // FIXME: The href attribute of the link element can be in "//hostname" + // form, and we shouldn't attempt to complete that as URL + // <https://bugs.webkit.org/show_bug.cgi?id=48857>. + if (settings && settings->GetDNSPrefetchingEnabled() && + params.href.IsValid() && !params.href.IsEmpty()) { + if (settings->GetLogDnsPrefetchAndPreconnect()) { + SendMessageToConsoleForPossiblyNullDocument( + ConsoleMessage::Create( + kOtherMessageSource, kVerboseMessageLevel, + String("DNS prefetch triggered for " + params.href.Host())), + document, frame); + } + network_hints_interface.DnsPrefetchHost(params.href.Host()); + } + } +} + +void PreloadHelper::PreconnectIfNeeded( + const LinkLoadParameters& params, + Document* document, + LocalFrame* frame, + const NetworkHintsInterface& network_hints_interface, + LinkCaller caller) { + if (params.rel.IsPreconnect() && params.href.IsValid() && + params.href.ProtocolIsInHTTPFamily()) { + UseCounter::Count(frame, WebFeature::kLinkRelPreconnect); + if (caller == kLinkCalledFromHeader) + UseCounter::Count(frame, WebFeature::kLinkHeaderPreconnect); + Settings* settings = frame ? frame->GetSettings() : nullptr; + if (settings && settings->GetLogDnsPrefetchAndPreconnect()) { + SendMessageToConsoleForPossiblyNullDocument( + ConsoleMessage::Create( + kOtherMessageSource, kVerboseMessageLevel, + String("Preconnect triggered for ") + params.href.GetString()), + document, frame); + if (params.cross_origin != kCrossOriginAttributeNotSet) { + SendMessageToConsoleForPossiblyNullDocument( + ConsoleMessage::Create(kOtherMessageSource, kVerboseMessageLevel, + String("Preconnect CORS setting is ") + + String((params.cross_origin == + kCrossOriginAttributeAnonymous) + ? "anonymous" + : "use-credentials")), + document, frame); + } + } + network_hints_interface.PreconnectHost(params.href, params.cross_origin); + } +} + +base::Optional<ResourceType> PreloadHelper::GetResourceTypeFromAsAttribute( + const String& as) { + DCHECK_EQ(as.DeprecatedLower(), as); + if (as == "image") + return ResourceType::kImage; + if (as == "script") + return ResourceType::kScript; + if (as == "style") + return ResourceType::kCSSStyleSheet; + if (as == "video") + return ResourceType::kVideo; + if (as == "audio") + return ResourceType::kAudio; + if (as == "track") + return ResourceType::kTextTrack; + if (as == "font") + return ResourceType::kFont; + if (as == "fetch") + return ResourceType::kRaw; + return base::nullopt; +} + +static bool MediaMatches(const String& media, MediaValues* media_values) { + scoped_refptr<MediaQuerySet> media_queries = MediaQuerySet::Create(media); + MediaQueryEvaluator evaluator(*media_values); + return evaluator.Eval(*media_queries); +} + +// |base_url| is used in Link HTTP Header based preloads to resolve relative +// URLs in srcset, which should be based on the resource's URL, not the +// document's base URL. If |base_url| is a null URL, relative URLs are resolved +// using |document.CompleteURL()|. +Resource* PreloadHelper::PreloadIfNeeded( + const LinkLoadParameters& params, + Document& document, + const KURL& base_url, + LinkCaller caller, + ViewportDescription* viewport_description, + ParserDisposition parser_disposition) { + if (!document.Loader() || !params.rel.IsLinkPreload()) + return nullptr; + + base::Optional<ResourceType> resource_type = + PreloadHelper::GetResourceTypeFromAsAttribute(params.as); + + MediaValues* media_values = nullptr; + KURL url; + if (resource_type == ResourceType::kImage && !params.image_srcset.IsEmpty() && + RuntimeEnabledFeatures::PreloadImageSrcSetEnabled()) { + media_values = CreateMediaValues(document, viewport_description); + float source_size = + SizesAttributeParser(media_values, params.image_sizes).length(); + ImageCandidate candidate = BestFitSourceForImageAttributes( + media_values->DevicePixelRatio(), source_size, params.href, + params.image_srcset); + url = base_url.IsNull() ? document.CompleteURL(candidate.ToString()) + : KURL(base_url, candidate.ToString()); + } else { + url = params.href; + } + + UseCounter::Count(document, WebFeature::kLinkRelPreload); + if (!url.IsValid() || url.IsEmpty()) { + document.AddConsoleMessage(ConsoleMessage::Create( + kOtherMessageSource, kWarningMessageLevel, + String("<link rel=preload> has an invalid `href` value"))); + return nullptr; + } + + // Preload only if media matches + if (!params.media.IsEmpty()) { + if (!media_values) + media_values = CreateMediaValues(document, viewport_description); + if (!MediaMatches(params.media, media_values)) + return nullptr; + } + + if (caller == kLinkCalledFromHeader) + UseCounter::Count(document, WebFeature::kLinkHeaderPreload); + if (resource_type == base::nullopt) { + document.AddConsoleMessage(ConsoleMessage::Create( + kOtherMessageSource, kWarningMessageLevel, + String("<link rel=preload> must have a valid `as` value"))); + return nullptr; + } + + if (!IsSupportedType(resource_type.value(), params.type)) { + document.AddConsoleMessage(ConsoleMessage::Create( + kOtherMessageSource, kWarningMessageLevel, + String("<link rel=preload> has an unsupported `type` value"))); + return nullptr; + } + ResourceRequest resource_request(url); + resource_request.SetRequestContext(ResourceFetcher::DetermineRequestContext( + resource_type.value(), ResourceFetcher::kImageNotImageSet, false)); + + resource_request.SetReferrerPolicy(params.referrer_policy); + + resource_request.SetFetchImportanceMode( + GetFetchImportanceAttributeValue(params.importance)); + + ResourceLoaderOptions options; + options.initiator_info.name = fetch_initiator_type_names::kLink; + options.parser_disposition = parser_disposition; + FetchParameters link_fetch_params(resource_request, options); + link_fetch_params.SetCharset(document.Encoding()); + + if (params.cross_origin != kCrossOriginAttributeNotSet) { + link_fetch_params.SetCrossOriginAccessControl(document.GetSecurityOrigin(), + params.cross_origin); + } + link_fetch_params.SetContentSecurityPolicyNonce(params.nonce); + Settings* settings = document.GetSettings(); + if (settings && settings->GetLogPreload()) { + document.AddConsoleMessage(ConsoleMessage::Create( + kOtherMessageSource, kVerboseMessageLevel, + String("Preload triggered for " + url.Host() + url.GetPath()))); + } + link_fetch_params.SetLinkPreload(true); + return PreloadHelper::StartPreload(resource_type.value(), link_fetch_params, + document.Fetcher()); +} + +// https://html.spec.whatwg.org/multipage/links.html#link-type-modulepreload +void PreloadHelper::ModulePreloadIfNeeded( + const LinkLoadParameters& params, + Document& document, + ViewportDescription* viewport_description, + SingleModuleClient* client) { + if (!document.Loader() || !params.rel.IsModulePreload()) + return; + + UseCounter::Count(document, WebFeature::kLinkRelModulePreload); + + // Step 1. "If the href attribute's value is the empty string, then return." + // [spec text] + if (params.href.IsEmpty()) { + document.AddConsoleMessage( + ConsoleMessage::Create(kOtherMessageSource, kWarningMessageLevel, + "<link rel=modulepreload> has no `href` value")); + return; + } + + // Step 5. "Let settings object be the link element's node document's relevant + // settings object." [spec text] + // |document| is the node document here, and its context document is the + // relevant settings object. + Document* context_document = document.ContextDocument(); + Modulator* modulator = + Modulator::From(ToScriptStateForMainWorld(context_document->GetFrame())); + DCHECK(modulator); + if (!modulator) + return; + + // Step 2. "Let destination be the current state of the as attribute (a + // destination), or "script" if it is in no state." [spec text] + // Step 3. "If destination is not script-like, then queue a task on the + // networking task source to fire an event named error at the link element, + // and return." [spec text] + // Currently we only support as="script". + if (!params.as.IsEmpty() && params.as != "script") { + document.AddConsoleMessage(ConsoleMessage::Create( + kOtherMessageSource, kWarningMessageLevel, + String("<link rel=modulepreload> has an invalid `as` value " + + params.as))); + // This triggers the same logic as Step 11 asynchronously, which will fire + // the error event. + if (client) { + modulator->TaskRunner()->PostTask( + FROM_HERE, WTF::Bind(&SingleModuleClient::NotifyModuleLoadFinished, + WrapPersistent(client), nullptr)); + } + return; + } + mojom::RequestContextType destination = mojom::RequestContextType::SCRIPT; + + // Step 4. "Parse the URL given by the href attribute, relative to the + // element's node document. If that fails, then return. Otherwise, let url be + // the resulting URL record." [spec text] + // |href| is already resolved in caller side. + if (!params.href.IsValid()) { + document.AddConsoleMessage(ConsoleMessage::Create( + kOtherMessageSource, kWarningMessageLevel, + "<link rel=modulepreload> has an invalid `href` value " + + params.href.GetString())); + return; + } + + // Preload only if media matches. + // https://html.spec.whatwg.org/#processing-the-media-attribute + if (!params.media.IsEmpty()) { + MediaValues* media_values = + CreateMediaValues(document, viewport_description); + if (!MediaMatches(params.media, media_values)) + return; + } + + // Step 6. "Let credentials mode be the module script credentials mode for the + // crossorigin attribute." [spec text] + network::mojom::FetchCredentialsMode credentials_mode = + ScriptLoader::ModuleScriptCredentialsMode(params.cross_origin); + + // Step 7. "Let cryptographic nonce be the value of the nonce attribute, if it + // is specified, or the empty string otherwise." [spec text] + // |nonce| parameter is the value of the nonce attribute. + + // Step 8. "Let integrity metadata be the value of the integrity attribute, if + // it is specified, or the empty string otherwise." [spec text] + IntegrityMetadataSet integrity_metadata; + if (!params.integrity.IsEmpty()) { + SubresourceIntegrity::IntegrityFeatures integrity_features = + SubresourceIntegrityHelper::GetFeatures(&document); + SubresourceIntegrity::ReportInfo report_info; + SubresourceIntegrity::ParseIntegrityAttribute( + params.integrity, integrity_features, integrity_metadata, &report_info); + SubresourceIntegrityHelper::DoReport(document, report_info); + } + + // Step 9. "Let referrer policy be the current state of the element's + // referrerpolicy attribute." [spec text] + // |referrer_policy| parameter is the value of the referrerpolicy attribute. + + // Step 10. "Let options be a script fetch options whose cryptographic nonce + // is cryptographic nonce, integrity metadata is integrity metadata, parser + // metadata is "not-parser-inserted", credentials mode is credentials mode, + // and referrer policy is referrer policy." [spec text] + ModuleScriptFetchRequest request( + params.href, destination, + ScriptFetchOptions(params.nonce, integrity_metadata, params.integrity, + kNotParserInserted, credentials_mode, + params.referrer_policy), + Referrer::NoReferrer(), TextPosition::MinimumPosition()); + + // Step 11. "Fetch a single module script given url, settings object, + // destination, options, settings object, "client", and with the top-level + // module fetch flag set. Wait until algorithm asynchronously completes with + // result." [spec text] + modulator->FetchSingle(request, context_document->Fetcher(), + ModuleGraphLevel::kDependentModuleFetch, + ModuleScriptCustomFetchType::kNone, client); + + Settings* settings = document.GetSettings(); + if (settings && settings->GetLogPreload()) { + document.AddConsoleMessage( + ConsoleMessage::Create(kOtherMessageSource, kVerboseMessageLevel, + "Module preload triggered for " + + params.href.Host() + params.href.GetPath())); + } + + // Asynchronously continue processing after + // client->NotifyModuleLoadFinished() is called. +} + +Resource* PreloadHelper::PrefetchIfNeeded(const LinkLoadParameters& params, + Document& document) { + if (params.rel.IsLinkPrefetch() && params.href.IsValid() && + document.GetFrame()) { + UseCounter::Count(document, WebFeature::kLinkRelPrefetch); + + ResourceRequest resource_request(params.href); + resource_request.SetReferrerPolicy(params.referrer_policy); + resource_request.SetFetchImportanceMode( + GetFetchImportanceAttributeValue(params.importance)); + + ResourceLoaderOptions options; + options.initiator_info.name = fetch_initiator_type_names::kLink; + + FetchParameters link_fetch_params(resource_request, options); + if (params.cross_origin != kCrossOriginAttributeNotSet) { + link_fetch_params.SetCrossOriginAccessControl( + document.GetSecurityOrigin(), params.cross_origin); + } + return LinkFetchResource::Fetch(ResourceType::kLinkPrefetch, + link_fetch_params, document.Fetcher()); + } + return nullptr; +} + +void PreloadHelper::LoadLinksFromHeader( + const String& header_value, + const KURL& base_url, + LocalFrame& frame, + Document* document, + const NetworkHintsInterface& network_hints_interface, + CanLoadResources can_load_resources, + MediaPreloadPolicy media_policy, + ViewportDescriptionWrapper* viewport_description_wrapper) { + if (header_value.IsEmpty()) + return; + LinkHeaderSet header_set(header_value); + for (auto& header : header_set) { + if (!header.Valid() || header.Url().IsEmpty() || header.Rel().IsEmpty()) + continue; + + if (media_policy == kOnlyLoadMedia && !header.IsViewportDependent()) + continue; + if (media_policy == kOnlyLoadNonMedia && header.IsViewportDependent()) + continue; + + const LinkLoadParameters params(header, base_url); + // Sanity check to avoid re-entrancy here. + if (params.href == base_url) + continue; + if (can_load_resources != kOnlyLoadResources) { + DnsPrefetchIfNeeded(params, document, &frame, network_hints_interface, + kLinkCalledFromHeader); + + PreconnectIfNeeded(params, document, &frame, network_hints_interface, + kLinkCalledFromHeader); + } + if (can_load_resources != kDoNotLoadResources) { + DCHECK(document); + ViewportDescription* viewport_description = + (viewport_description_wrapper && viewport_description_wrapper->set) + ? &(viewport_description_wrapper->description) + : nullptr; + + PreloadIfNeeded(params, *document, base_url, kLinkCalledFromHeader, + viewport_description, kNotParserInserted); + PrefetchIfNeeded(params, *document); + ModulePreloadIfNeeded(params, *document, viewport_description, nullptr); + } + if (params.rel.IsServiceWorker()) { + UseCounter::Count(&frame, WebFeature::kLinkHeaderServiceWorker); + } + // TODO(yoav): Add more supported headers as needed. + } +} + +Resource* PreloadHelper::StartPreload(ResourceType type, + FetchParameters& params, + ResourceFetcher* resource_fetcher) { + Resource* resource = nullptr; + switch (type) { + case ResourceType::kImage: + resource = ImageResource::Fetch(params, resource_fetcher); + break; + case ResourceType::kScript: + params.SetRequestContext(mojom::RequestContextType::SCRIPT); + resource = ScriptResource::Fetch(params, resource_fetcher, nullptr, + ScriptResource::kAllowStreaming); + break; + case ResourceType::kCSSStyleSheet: + resource = + CSSStyleSheetResource::Fetch(params, resource_fetcher, nullptr); + break; + case ResourceType::kFont: + resource = FontResource::Fetch(params, resource_fetcher, nullptr); + break; + case ResourceType::kAudio: + case ResourceType::kVideo: + resource = RawResource::FetchMedia(params, resource_fetcher, nullptr); + break; + case ResourceType::kTextTrack: + resource = RawResource::FetchTextTrack(params, resource_fetcher, nullptr); + break; + case ResourceType::kImportResource: + resource = RawResource::FetchImport(params, resource_fetcher, nullptr); + break; + case ResourceType::kRaw: + resource = RawResource::Fetch(params, resource_fetcher, nullptr); + break; + default: + NOTREACHED(); + } + + return resource; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/loader/preload_helper.h b/third_party/blink/renderer/core/loader/preload_helper.h new file mode 100644 index 0000000..d4a63ebb --- /dev/null +++ b/third_party/blink/renderer/core/loader/preload_helper.h
@@ -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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_PRELOAD_HELPER_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_PRELOAD_HELPER_H_ + +#include "base/optional.h" +#include "third_party/blink/renderer/platform/loader/fetch/resource.h" + +namespace blink { + +class Document; +class LocalFrame; +class NetworkHintsInterface; +class SingleModuleClient; +struct LinkLoadParameters; +struct ViewportDescription; +struct ViewportDescriptionWrapper; + +// PreloadHelper is a helper class for preload, module preload, prefetch, +// DNS prefetch, and preconnect triggered by <link> elements and "Link" HTTP +// response headers. +class PreloadHelper final { + STATIC_ONLY(PreloadHelper); + + public: + enum CanLoadResources { + kOnlyLoadResources, + kDoNotLoadResources, + kLoadResourcesAndPreconnect + }; + + // Media links cannot be preloaded until the first chunk is parsed. The rest + // can be preloaded at commit time. + enum MediaPreloadPolicy { kLoadAll, kOnlyLoadNonMedia, kOnlyLoadMedia }; + + static void LoadLinksFromHeader(const String& header_value, + const KURL& base_url, + LocalFrame&, + Document*, // can be nullptr + const NetworkHintsInterface&, + CanLoadResources, + MediaPreloadPolicy, + ViewportDescriptionWrapper*); + static Resource* StartPreload(ResourceType, + FetchParameters&, + ResourceFetcher*); + + // Currently only used for UseCounter. + enum LinkCaller { + kLinkCalledFromHeader, + kLinkCalledFromMarkup, + }; + + static void DnsPrefetchIfNeeded(const LinkLoadParameters&, + Document*, + LocalFrame*, + const NetworkHintsInterface&, + LinkCaller); + static void PreconnectIfNeeded(const LinkLoadParameters&, + Document*, + LocalFrame*, + const NetworkHintsInterface&, + LinkCaller); + static Resource* PrefetchIfNeeded(const LinkLoadParameters&, Document&); + static Resource* PreloadIfNeeded(const LinkLoadParameters&, + Document&, + const KURL& base_url, + LinkCaller, + ViewportDescription*, + ParserDisposition); + static void ModulePreloadIfNeeded(const LinkLoadParameters&, + Document&, + ViewportDescription*, + SingleModuleClient*); + + static base::Optional<ResourceType> GetResourceTypeFromAsAttribute( + const String& as); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_PRELOAD_HELPER_H_
diff --git a/third_party/blink/renderer/core/loader/threadable_loader.cc b/third_party/blink/renderer/core/loader/threadable_loader.cc index 42310ac..289de9bb2 100644 --- a/third_party/blink/renderer/core/loader/threadable_loader.cc +++ b/third_party/blink/renderer/core/loader/threadable_loader.cc
@@ -810,8 +810,9 @@ if (!frame) return; DocumentLoader* loader = frame->Loader().GetDocumentLoader(); - probe::didReceiveResourceResponse(execution_context_, identifier, loader, - response, GetResource()); + probe::didReceiveResourceResponse(probe::ToCoreProbeSink(execution_context_), + identifier, loader, response, + GetResource()); frame->Console().ReportResourceResponseReceived(loader, identifier, response); }
diff --git a/third_party/blink/renderer/core/loader/worker_fetch_context.cc b/third_party/blink/renderer/core/loader/worker_fetch_context.cc index 64250bc5..bd2d8ce 100644 --- a/third_party/blink/renderer/core/loader/worker_fetch_context.cc +++ b/third_party/blink/renderer/core/loader/worker_fetch_context.cc
@@ -73,7 +73,7 @@ bool WorkerFetchContext::ShouldBlockRequestByInspector(const KURL& url) const { bool should_block_request = false; - probe::shouldBlockRequest(global_scope_, url, &should_block_request); + probe::shouldBlockRequest(Probe(), url, &should_block_request); return should_block_request; } @@ -105,6 +105,10 @@ Deprecation::CountDeprecation(global_scope_, feature); } +CoreProbeSink* WorkerFetchContext::Probe() const { + return probe::ToCoreProbeSink(static_cast<ExecutionContext*>(global_scope_)); +} + bool WorkerFetchContext::ShouldBlockWebSocketByMixedContentCheck( const KURL& url) const { // Worklets don't support WebSocket. @@ -233,7 +237,7 @@ void WorkerFetchContext::PrepareRequest(ResourceRequest& request, RedirectType) { String user_agent = global_scope_->UserAgent(); - probe::applyUserAgentOverride(global_scope_, &user_agent); + probe::applyUserAgentOverride(Probe(), &user_agent); DCHECK(!user_agent.IsNull()); request.SetHTTPUserAgent(AtomicString(user_agent)); @@ -280,20 +284,20 @@ web_context_->DidDisplayContentWithCertificateErrors(); } } - probe::didReceiveResourceResponse(global_scope_, identifier, nullptr, - response, resource); + probe::didReceiveResourceResponse(Probe(), identifier, nullptr, response, + resource); } void WorkerFetchContext::DispatchDidReceiveData(unsigned long identifier, const char* data, size_t data_length) { - probe::didReceiveData(global_scope_, identifier, nullptr, data, data_length); + probe::didReceiveData(Probe(), identifier, nullptr, data, data_length); } void WorkerFetchContext::DispatchDidReceiveEncodedData( unsigned long identifier, size_t encoded_data_length) { - probe::didReceiveEncodedDataLength(global_scope_, nullptr, identifier, + probe::didReceiveEncodedDataLength(Probe(), nullptr, identifier, encoded_data_length); } @@ -303,7 +307,7 @@ int64_t encoded_data_length, int64_t decoded_body_length, bool should_report_corb_blocking) { - probe::didFinishLoading(global_scope_, identifier, nullptr, finish_time, + probe::didFinishLoading(Probe(), identifier, nullptr, finish_time, encoded_data_length, decoded_body_length, should_report_corb_blocking); } @@ -313,7 +317,7 @@ const ResourceError& error, int64_t encoded_data_length, bool is_internal_request) { - probe::didFailLoading(global_scope_, identifier, nullptr, error); + probe::didFailLoading(Probe(), identifier, nullptr, error); if (network_utils::IsCertificateTransparencyRequiredError( error.ErrorCode())) { CountUsage(WebFeature::kCertificateTransparencyRequiredErrorOnResourceLoad);
diff --git a/third_party/blink/renderer/core/loader/worker_fetch_context.h b/third_party/blink/renderer/core/loader/worker_fetch_context.h index 3a793d27..675e278 100644 --- a/third_party/blink/renderer/core/loader/worker_fetch_context.h +++ b/third_party/blink/renderer/core/loader/worker_fetch_context.h
@@ -15,6 +15,7 @@ namespace blink { +class CoreProbeSink; class Resource; class SubresourceFilter; class WebURLLoader; @@ -126,6 +127,8 @@ private: void SetFirstPartyCookie(ResourceRequest&); + CoreProbeSink* Probe() const; + const Member<WorkerOrWorkletGlobalScope> global_scope_; const scoped_refptr<WebWorkerFetchContext> web_context_;
diff --git a/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.idl b/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.idl index e939cf9..115e1a3 100644 --- a/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.idl +++ b/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.idl
@@ -14,6 +14,6 @@ attribute [EnforceRange] unsigned long width; attribute [EnforceRange] unsigned long height; - [CallWith=ScriptState, RaisesException] ImageBitmap transferToImageBitmap(); - [MeasureAs=OffscreenCanvasConvertToBlob, RaisesException, CallWith=ScriptState] Promise<Blob> convertToBlob(optional ImageEncodeOptions options); + [CallWith=ScriptState, HighEntropy, MeasureAs=OffscreenCanvasTransferToImageBitmap, RaisesException] ImageBitmap transferToImageBitmap(); + [CallWith=ScriptState, HighEntropy, MeasureAs=OffscreenCanvasConvertToBlob, RaisesException] Promise<Blob> convertToBlob(optional ImageEncodeOptions options); };
diff --git a/third_party/blink/renderer/core/page/chrome_client.h b/third_party/blink/renderer/core/page/chrome_client.h index 2d4ca19..3a06e500 100644 --- a/third_party/blink/renderer/core/page/chrome_client.h +++ b/third_party/blink/renderer/core/page/chrome_client.h
@@ -216,6 +216,10 @@ return base::nullopt; } + // Returns the scale used to convert incoming input events while emulating + // device metics. + virtual float InputEventsScaleForEmulation() const { return 1; } + virtual void DispatchViewportPropertiesDidChange( const ViewportDescription&) const {}
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.cc b/third_party/blink/renderer/core/page/chrome_client_impl.cc index b883180..07371aa 100644 --- a/third_party/blink/renderer/core/page/chrome_client_impl.cc +++ b/third_party/blink/renderer/core/page/chrome_client_impl.cc
@@ -462,6 +462,10 @@ return web_view_->GetDevToolsEmulator()->VisibleContentRectForPainting(); } +float ChromeClientImpl::InputEventsScaleForEmulation() const { + return web_view_->GetDevToolsEmulator()->InputEventsScaleForEmulation(); +} + void ChromeClientImpl::ContentsSizeChanged(LocalFrame* frame, const IntSize& size) const { web_view_->DidChangeContentsSize();
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.h b/third_party/blink/renderer/core/page/chrome_client_impl.h index 3260c37..fe8bb83 100644 --- a/third_party/blink/renderer/core/page/chrome_client_impl.h +++ b/third_party/blink/renderer/core/page/chrome_client_impl.h
@@ -113,6 +113,7 @@ float WindowToViewportScalar(const float) const override; WebScreenInfo GetScreenInfo() const override; base::Optional<IntRect> VisibleContentRectForPainting() const override; + float InputEventsScaleForEmulation() const override; void ContentsSizeChanged(LocalFrame*, const IntSize&) const override; bool DoubleTapToZoomEnabled() const override; void PageScaleFactorChanged() const override;
diff --git a/third_party/blink/renderer/core/page/context_menu_controller.cc b/third_party/blink/renderer/core/page/context_menu_controller.cc index d3b2766..fb3fe6f 100644 --- a/third_party/blink/renderer/core/page/context_menu_controller.cc +++ b/third_party/blink/renderer/core/page/context_menu_controller.cc
@@ -128,17 +128,12 @@ : nullptr; } -// Figure out the URL of a page or subframe. Returns |page_type| as the type, -// which indicates page or subframe, or ContextNodeType::kNone if the URL could -// not be determined for some reason. +// Figure out the URL of a page or subframe. static KURL UrlFromFrame(LocalFrame* frame) { if (frame) { DocumentLoader* document_loader = frame->Loader().GetDocumentLoader(); - if (document_loader) { - return document_loader->UnreachableURL().IsEmpty() - ? document_loader->GetRequest().Url() - : document_loader->UnreachableURL(); - } + if (document_loader) + return document_loader->UrlForHistory(); } return KURL(); }
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc index dccc8cf..5c0424f5 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
@@ -246,8 +246,10 @@ } frame_view->ClearFrameIsScrollableDidChange(); - // TODO(pdr): Skip this callsite when blink generates property trees. - UpdateUserInputScrollable(&page_->GetVisualViewport()); + // When blink generates property trees, the user input scrollable bits are + // stored on scroll nodes instead of layers. + if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) + UpdateUserInputScrollable(&page_->GetVisualViewport()); } template <typename Function> @@ -527,7 +529,8 @@ if (!page_ || !page_->MainFrame()) return; - UpdateUserInputScrollable(scrollable_area); + if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) + UpdateUserInputScrollable(scrollable_area); cc::Layer* cc_layer = GraphicsLayerToCcLayer(scrollable_area->LayerForScrolling()); @@ -808,10 +811,11 @@ } } -// TODO(pdr): When blink generates property trees, the user input scrollable -// bits are stored on scroll nodes instead of layers so this should be removed. void ScrollingCoordinator::UpdateUserInputScrollable( ScrollableArea* scrollable_area) { + // When blink generates property trees, the user input scrollable bits are + // stored on scroll nodes instead of layers so this is not needed. + DCHECK(!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()); cc::Layer* cc_layer = GraphicsLayerToCcLayer(scrollable_area->LayerForScrolling()); if (cc_layer) {
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc index 9473160..feb84a5c 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc
@@ -1127,8 +1127,8 @@ cc::Layer* cc_scroll_layer = composited_layer_mapping->ScrollingContentsLayer()->CcLayer(); ASSERT_TRUE(cc_scroll_layer->scrollable()); - ASSERT_TRUE(cc_scroll_layer->user_scrollable_horizontal()); - ASSERT_TRUE(cc_scroll_layer->user_scrollable_vertical()); + ASSERT_TRUE(cc_scroll_layer->GetUserScrollableHorizontal()); + ASSERT_TRUE(cc_scroll_layer->GetUserScrollableVertical()); #if defined(OS_ANDROID) // Now verify we've attached impl-side scrollbars onto the scrollbar layers @@ -1168,8 +1168,8 @@ cc::Layer* cc_scroll_layer = composited_layer_mapping->ScrollingContentsLayer()->CcLayer(); ASSERT_TRUE(cc_scroll_layer->scrollable()); - ASSERT_TRUE(cc_scroll_layer->user_scrollable_horizontal()); - ASSERT_FALSE(cc_scroll_layer->user_scrollable_vertical()); + ASSERT_TRUE(cc_scroll_layer->GetUserScrollableHorizontal()); + ASSERT_FALSE(cc_scroll_layer->GetUserScrollableVertical()); overflow_element = GetFrame()->GetDocument()->getElementById("unscrollable-x"); @@ -1190,8 +1190,8 @@ cc_scroll_layer = composited_layer_mapping->ScrollingContentsLayer()->CcLayer(); ASSERT_TRUE(cc_scroll_layer->scrollable()); - ASSERT_FALSE(cc_scroll_layer->user_scrollable_horizontal()); - ASSERT_TRUE(cc_scroll_layer->user_scrollable_vertical()); + ASSERT_FALSE(cc_scroll_layer->GetUserScrollableHorizontal()); + ASSERT_TRUE(cc_scroll_layer->GetUserScrollableVertical()); } TEST_P(ScrollingCoordinatorTest, iframeScrolling) {
diff --git a/third_party/blink/renderer/core/page/viewport_test.cc b/third_party/blink/renderer/core/page/viewport_test.cc index ad676013..92591e2 100644 --- a/third_party/blink/renderer/core/page/viewport_test.cc +++ b/third_party/blink/renderer/core/page/viewport_test.cc
@@ -58,8 +58,6 @@ namespace blink { -using blink::test::RunPendingTasks; - class ViewportTest : public testing::Test { protected: ViewportTest() @@ -85,7 +83,7 @@ void ExecuteScript(WebLocalFrame* frame, const WebString& code) { frame->ExecuteScript(WebScriptSource(code)); - RunPendingTasks(); + blink::test::RunPendingTasks(); } std::string base_url_; @@ -3286,7 +3284,7 @@ request.Complete(responseText); // Pump the task queue so the meta tag gets processed. - test::RunPendingTasks(); + blink::test::RunPendingTasks(); } HistogramTester histogram_tester_;
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 88c74009..80d3cb9 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
@@ -2433,7 +2433,11 @@ bool layer_changed = false; if (needs_scrolling_layers) { if (scrolling_layer_) { - if (scrolling_coordinator) { + // When blink generates property trees, the user input scrollable bits are + // stored on scroll nodes instead of layers so there is no need to update + // them here. + if (scrolling_coordinator && + !RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) { scrolling_coordinator->UpdateUserInputScrollable( owning_layer_.GetScrollableArea()); }
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc index 2550f46b..6ee2e8f8 100644 --- a/third_party/blink/renderer/core/paint/paint_layer.cc +++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -148,8 +148,10 @@ #endif has3d_transformed_descendant_(false), contains_dirty_overlay_scrollbars_(false), - needs_ancestor_dependent_compositing_inputs_update_(true), - child_needs_compositing_inputs_update_(true), + needs_ancestor_dependent_compositing_inputs_update_( + !RuntimeEnabledFeatures::CompositeAfterPaintEnabled()), + child_needs_compositing_inputs_update_( + !RuntimeEnabledFeatures::CompositeAfterPaintEnabled()), has_compositing_descendant_(false), should_isolate_composited_descendants_(false), lost_grouped_mapping_(false), @@ -167,7 +169,8 @@ filter_on_effect_node_dirty_(false), is_under_svg_hidden_container_(false), descendant_has_direct_or_scrolling_compositing_reason_(false), - needs_compositing_reasons_update_(true), + needs_compositing_reasons_update_( + !RuntimeEnabledFeatures::CompositeAfterPaintEnabled()), descendant_may_need_compositing_requirements_update_(false), needs_compositing_layer_assignment_(false), descendant_needs_compositing_layer_assignment_(false), @@ -1054,12 +1057,15 @@ // TODO(chrishtr): These are a bit of a heavy hammer, because not all // things which require compositing inputs update require a descendant- - // dependent flags udpate. Reduce call sites after CAP launch allows + // dependent flags update. Reduce call sites after CAP launch allows /// removal of CompositingInputsUpdater. MarkAncestorChainForDescendantDependentFlagsUpdate(); } void PaintLayer::SetNeedsCompositingInputsUpdateInternal() { + if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) + return; + needs_ancestor_dependent_compositing_inputs_update_ = true; for (PaintLayer* current = this; @@ -1075,11 +1081,13 @@ void PaintLayer::UpdateAncestorDependentCompositingInputs( const AncestorDependentCompositingInputs& compositing_inputs) { + DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); EnsureAncestorDependentCompositingInputs() = compositing_inputs; needs_ancestor_dependent_compositing_inputs_update_ = false; } void PaintLayer::ClearChildNeedsCompositingInputsUpdate() { + DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); DCHECK(!NeedsCompositingInputsUpdate()); child_needs_compositing_inputs_update_ = false; }
diff --git a/third_party/blink/renderer/core/paint/paint_layer_test.cc b/third_party/blink/renderer/core/paint/paint_layer_test.cc index 1686057a..3e6ebbd 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_test.cc
@@ -1742,7 +1742,8 @@ LayoutRect(0, 0, 100, 100), false)); } -TEST_P(PaintLayerTest, ChangeAlphaNeedsCompositingInputs) { +TEST_P(PaintLayerTest, + ChangeAlphaNeedsCompositingInputsAndPaintPropertyUpdate) { SetBodyInnerHTML(R"HTML( <style> #target { @@ -1756,10 +1757,20 @@ </div> )HTML"); PaintLayer* target = GetPaintLayerByElementId("target"); + EXPECT_FALSE(target->NeedsCompositingInputsUpdate()); + EXPECT_FALSE(target->GetLayoutObject().NeedsPaintPropertyUpdate()); + EXPECT_FALSE(target->Parent()->GetLayoutObject().NeedsPaintPropertyUpdate()); + StyleDifference diff; diff.SetHasAlphaChanged(); target->StyleDidChange(diff, target->GetLayoutObject().Style()); - EXPECT_TRUE(target->NeedsCompositingInputsUpdate()); + if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) + EXPECT_FALSE(target->NeedsCompositingInputsUpdate()); + else + EXPECT_TRUE(target->NeedsCompositingInputsUpdate()); + EXPECT_TRUE(target->GetLayoutObject().NeedsPaintPropertyUpdate()); + // See the TODO in PaintLayer::SetNeedsCompositingInputsUpdate(). + EXPECT_TRUE(target->Parent()->GetLayoutObject().NeedsPaintPropertyUpdate()); } } // namespace blink
diff --git a/third_party/blink/renderer/core/probe/core_probes.h b/third_party/blink/renderer/core/probe/core_probes.h index affdc6a..1e2a421 100644 --- a/third_party/blink/renderer/core/probe/core_probes.h +++ b/third_party/blink/renderer/core/probe/core_probes.h
@@ -81,6 +81,10 @@ return document ? ToCoreProbeSink(*document) : nullptr; } +inline CoreProbeSink* ToCoreProbeSink(CoreProbeSink* sink) { + return sink; +} + inline CoreProbeSink* ToCoreProbeSink(ExecutionContext* context) { return context ? context->GetProbeSink() : nullptr; }
diff --git a/third_party/blink/renderer/core/probe/core_probes.pidl b/third_party/blink/renderer/core/probe/core_probes.pidl index 6c599a2..4593311 100644 --- a/third_party/blink/renderer/core/probe/core_probes.pidl +++ b/third_party/blink/renderer/core/probe/core_probes.pidl
@@ -87,18 +87,18 @@ void didResizeMainFrame(LocalFrame*); void didPaint(LocalFrame*, const GraphicsLayer*, GraphicsContext&, const LayoutRect&); void applyAcceptLanguageOverride(ExecutionContext*, String* acceptLanguage); - void applyUserAgentOverride(ExecutionContext*, String* userAgent); + void applyUserAgentOverride(CoreProbeSink*, String* userAgent); void didBlockRequest([Keep] ExecutionContext*, const ResourceRequest&, DocumentLoader*, const FetchInitiatorInfo&, ResourceRequestBlockedReason, ResourceType); void didChangeResourcePriority(LocalFrame*, DocumentLoader*, unsigned long identifier, ResourceLoadPriority loadPriority); void willSendRequest([Keep] ExecutionContext*, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, const FetchInitiatorInfo&, ResourceType); void markResourceAsCached(LocalFrame*, DocumentLoader*, unsigned long identifier); - void didReceiveResourceResponse(ExecutionContext*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, Resource*); - void didReceiveData(ExecutionContext*, unsigned long identifier, DocumentLoader*, const char* data, size_t dataLength); - void didReceiveBlob(ExecutionContext*, unsigned long identifier, DocumentLoader*, BlobDataHandle*); - void didReceiveEncodedDataLength(ExecutionContext*, DocumentLoader* loader, unsigned long identifier, size_t encodedDataLength); - void didFinishLoading(ExecutionContext*, unsigned long identifier, DocumentLoader*, TimeTicks finishTime, int64_t encoded_data_length, int64_t decodedBodyLength, bool should_report_corb_blocking); + void didReceiveResourceResponse(CoreProbeSink*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, Resource*); + void didReceiveData(CoreProbeSink*, unsigned long identifier, DocumentLoader*, const char* data, size_t dataLength); + void didReceiveBlob(CoreProbeSink*, unsigned long identifier, DocumentLoader*, BlobDataHandle*); + void didReceiveEncodedDataLength(CoreProbeSink*, DocumentLoader* loader, unsigned long identifier, size_t encodedDataLength); + void didFinishLoading(CoreProbeSink*, unsigned long identifier, DocumentLoader*, TimeTicks finishTime, int64_t encoded_data_length, int64_t decodedBodyLength, bool should_report_corb_blocking); void didReceiveCorsRedirectResponse(ExecutionContext*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, Resource*); - void didFailLoading(ExecutionContext*, unsigned long identifier, DocumentLoader*, const ResourceError&); + void didFailLoading(CoreProbeSink*, unsigned long identifier, DocumentLoader*, const ResourceError&); void willSendEventSourceRequest(ExecutionContext*, ThreadableLoaderClient* eventSource); void willDispatchEventSourceEvent(ExecutionContext*, unsigned long identifier, const AtomicString& eventName, const AtomicString& eventId, const String& data); void willLoadXHR(ExecutionContext*, XMLHttpRequest* xhr, ThreadableLoaderClient* client, const AtomicString& method, const KURL& url, bool async, const HTTPHeaderMap& headers, bool includeCredentials); @@ -151,7 +151,7 @@ ParseHTML(Document* document, HTMLDocumentParser* parser); void forcePseudoState([Keep] Element* element, CSSSelector::PseudoType pseudoState, bool* result); void shouldForceCorsPreflight(ExecutionContext*, bool* result); - void shouldBlockRequest(ExecutionContext*, const KURL&, bool* result); + void shouldBlockRequest(CoreProbeSink*, const KURL&, bool* result); void shouldBypassServiceWorker(ExecutionContext* context, bool* result); void consoleTimeStamp(ExecutionContext*, const String& title); void lifecycleEvent([Keep] LocalFrame*, DocumentLoader*, const char* name, double timestamp);
diff --git a/third_party/blink/renderer/core/svg/svg_element.cc b/third_party/blink/renderer/core/svg/svg_element.cc index 630704be..2a888df 100644 --- a/third_party/blink/renderer/core/svg/svg_element.cc +++ b/third_party/blink/renderer/core/svg/svg_element.cc
@@ -33,6 +33,7 @@ #include "third_party/blink/renderer/core/animation/keyframe_effect.h" #include "third_party/blink/renderer/core/animation/svg_interpolation_environment.h" #include "third_party/blink/renderer/core/animation/svg_interpolation_types_map.h" +#include "third_party/blink/renderer/core/css/css_property_id_templates.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/element_traversal.h"
diff --git a/third_party/blink/renderer/core/svg/svg_geometry_element.idl b/third_party/blink/renderer/core/svg/svg_geometry_element.idl index 445c15b..8145d5c 100644 --- a/third_party/blink/renderer/core/svg/svg_geometry_element.idl +++ b/third_party/blink/renderer/core/svg/svg_geometry_element.idl
@@ -34,8 +34,8 @@ [SameObject] readonly attribute SVGAnimatedNumber pathLength; // TODO(foolip): SVGPoint should be DOMPoint. - boolean isPointInFill(SVGPoint point); - boolean isPointInStroke(SVGPoint point); - float getTotalLength(); - SVGPoint getPointAtLength(float distance); + [HighEntropy, Measure] boolean isPointInFill(SVGPoint point); + [HighEntropy, Measure] boolean isPointInStroke(SVGPoint point); + [HighEntropy, Measure] float getTotalLength(); + [HighEntropy, Measure] SVGPoint getPointAtLength(float distance); };
diff --git a/third_party/blink/renderer/core/svg/svg_text_content_element.idl b/third_party/blink/renderer/core/svg/svg_text_content_element.idl index 4617f7f..6557fcf 100644 --- a/third_party/blink/renderer/core/svg/svg_text_content_element.idl +++ b/third_party/blink/renderer/core/svg/svg_text_content_element.idl
@@ -35,12 +35,12 @@ [MeasureAs=SVG1DOMText] readonly attribute SVGAnimatedEnumeration lengthAdjust; long getNumberOfChars(); - float getComputedTextLength(); - [RaisesException] float getSubStringLength(unsigned long charnum, unsigned long nchars); + [HighEntropy, Measure] float getComputedTextLength(); + [HighEntropy, Measure, RaisesException] float getSubStringLength(unsigned long charnum, unsigned long nchars); // TODO(foolip): SVGPoint/SVGRect should be DOMPoint/DOMRect. - [RaisesException] SVGPoint getStartPositionOfChar(unsigned long charnum); - [RaisesException] SVGPoint getEndPositionOfChar(unsigned long charnum); - [RaisesException] SVGRect getExtentOfChar(unsigned long charnum); + [HighEntropy, Measure, RaisesException] SVGPoint getStartPositionOfChar(unsigned long charnum); + [HighEntropy, Measure, RaisesException] SVGPoint getEndPositionOfChar(unsigned long charnum); + [HighEntropy, Measure, RaisesException] SVGRect getExtentOfChar(unsigned long charnum); [RaisesException] float getRotationOfChar(unsigned long charnum); [RaisesException] long getCharNumAtPosition(SVGPoint point); [RaisesException] void selectSubString(unsigned long charnum, unsigned long nchars);
diff --git a/third_party/blink/renderer/core/workers/global_scope_creation_params.h b/third_party/blink/renderer/core/workers/global_scope_creation_params.h index 113e5d0..395e3bf 100644 --- a/third_party/blink/renderer/core/workers/global_scope_creation_params.h +++ b/third_party/blink/renderer/core/workers/global_scope_creation_params.h
@@ -7,7 +7,6 @@ #include <memory> #include "base/macros.h" -#include "base/optional.h" #include "base/unguessable_token.h" #include "services/network/public/mojom/referrer_policy.mojom-shared.h" #include "services/service_manager/public/mojom/interface_provider.mojom-blink.h" @@ -18,14 +17,11 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_cache_options.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" -#include "third_party/blink/renderer/core/script/script.h" #include "third_party/blink/renderer/core/workers/worker_clients.h" #include "third_party/blink/renderer/core/workers/worker_settings.h" #include "third_party/blink/renderer/core/workers/worklet_module_responses_map.h" #include "third_party/blink/renderer/platform/graphics/begin_frame_provider.h" #include "third_party/blink/renderer/platform/loader/fetch/https_state.h" -#include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h" -#include "third_party/blink/renderer/platform/network/content_security_policy_response_headers.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/wtf/forward.h" @@ -82,13 +78,7 @@ scoped_refptr<WebWorkerFetchContext> web_worker_fetch_context; - // |content_security_policy_parsed_headers| and - // |content_security_policy_raw_headers| are mutually exclusive. - // |content_security_policy_parsed_headers| is an empty vector - // when |content_security_policy_raw_headers| is set. Vector<CSPHeaderAndType> content_security_policy_parsed_headers; - base::Optional<ContentSecurityPolicyResponseHeaders> - content_security_policy_raw_headers; network::mojom::ReferrerPolicy referrer_policy; std::unique_ptr<Vector<String>> origin_trial_tokens;
diff --git a/third_party/blink/renderer/devtools/front_end/components/JSPresentationUtils.js b/third_party/blink/renderer/devtools/front_end/components/JSPresentationUtils.js index 0575375..3e74bea 100644 --- a/third_party/blink/renderer/devtools/front_end/components/JSPresentationUtils.js +++ b/third_party/blink/renderer/devtools/front_end/components/JSPresentationUtils.js
@@ -44,6 +44,7 @@ const shadowRoot = UI.createShadowRootWithCoreStyles(element, 'components/jsUtils.css'); const contentElement = shadowRoot.createChild('table', 'stack-preview-container'); let totalHiddenCallFramesCount = 0; + let totalCallFramesCount = 0; /** @type {!Array<!Element>} */ const links = []; @@ -54,6 +55,8 @@ function appendStackTrace(stackTrace) { let hiddenCallFrames = 0; for (const stackFrame of stackTrace.callFrames) { + totalCallFramesCount++; + let shouldHide = totalCallFramesCount > 30 && stackTrace.callFrames.length > 31; const row = createElement('tr'); row.createChild('td').textContent = '\n'; row.createChild('td', 'function-name').textContent = UI.beautifyFunctionName(stackFrame.functionName); @@ -61,14 +64,16 @@ if (link) { link.addEventListener('contextmenu', populateContextMenu.bind(null, link)); const uiLocation = Components.Linkifier.uiLocation(link); - if (uiLocation && Bindings.blackboxManager.isBlackboxedUISourceCode(uiLocation.uiSourceCode)) { - row.classList.add('blackboxed'); - ++hiddenCallFrames; - } + if (uiLocation && Bindings.blackboxManager.isBlackboxedUISourceCode(uiLocation.uiSourceCode)) + shouldHide = true; row.createChild('td').textContent = ' @ '; row.createChild('td').appendChild(link); links.push(link); } + if (shouldHide) { + row.classList.add('blackboxed'); + ++hiddenCallFrames; + } contentElement.appendChild(row); } totalHiddenCallFramesCount += hiddenCallFrames; @@ -125,9 +130,9 @@ cell.colSpan = 4; const showAllLink = cell.createChild('span', 'link'); if (totalHiddenCallFramesCount === 1) - showAllLink.textContent = ls`Show 1 more blackboxed frame`; + showAllLink.textContent = ls`Show 1 more frame`; else - showAllLink.textContent = ls`Show ${totalHiddenCallFramesCount} more blackboxed frames`; + showAllLink.textContent = ls`Show ${totalHiddenCallFramesCount} more frames`; showAllLink.addEventListener('click', () => { contentElement.classList.add('show-blackboxed'); if (contentUpdated)
diff --git a/third_party/blink/renderer/devtools/front_end/cookie_table/CookiesTable.js b/third_party/blink/renderer/devtools/front_end/cookie_table/CookiesTable.js index 051561f..cee144f 100644 --- a/third_party/blink/renderer/devtools/front_end/cookie_table/CookiesTable.js +++ b/third_party/blink/renderer/devtools/front_end/cookie_table/CookiesTable.js
@@ -349,12 +349,16 @@ } else { data.domain = cookie.domain() || ''; data.path = cookie.path() || ''; - if (cookie.maxAge()) + if (cookie.maxAge()) { data.expires = Number.secondsToString(parseInt(cookie.maxAge(), 10)); - else if (cookie.expires()) - data.expires = new Date(cookie.expires()).toISOString(); - else + } else if (cookie.expires()) { + if (cookie.expires() < 0) + data.expires = 'N/A'; + else + data.expires = new Date(cookie.expires()).toISOString(); + } else { data.expires = CookieTable.CookiesTable._expiresSessionValue; + } } data.size = cookie.size(); const checkmark = '\u2713';
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc index f0596cce..0e37d45 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc
@@ -14,6 +14,7 @@ : request_(request), script_state_(script_state) { DCHECK(request_); DCHECK(script_state_); + response_ready_property_ = MakeGarbageCollected<ResponseReadyProperty>( ExecutionContext::From(script_state), this, ResponseReadyProperty::kResponseReady); @@ -22,9 +23,8 @@ BackgroundFetchRecord::~BackgroundFetchRecord() = default; void BackgroundFetchRecord::ResolveResponseReadyProperty(Response* response) { - if (!response_ready_property_ || - response_ready_property_->GetState() != - ScriptPromisePropertyBase::State::kPending) { + if (response_ready_property_->GetState() != + ScriptPromisePropertyBase::State::kPending) { return; } @@ -45,7 +45,7 @@ if (!script_state_->ContextIsValid()) return; - // TODO(crbug.com/875201):Per https://wicg.github.io/background-fetch/ + // TODO(crbug.com/875201): Per https://wicg.github.io/background-fetch/ // #background-fetch-response-exposed, this should be resolved with a // TypeError. Figure out a way to do so. // Rejecting this with a TypeError here doesn't work because the @@ -68,6 +68,8 @@ BackgroundFetchRecord::State updated_state) { DCHECK_EQ(record_state_, State::kPending); + if (!script_state_->ContextIsValid()) + return; record_state_ = updated_state; ResolveResponseReadyProperty(/* updated_response = */ nullptr); } @@ -81,6 +83,7 @@ return; record_state_ = State::kSettled; + ScriptState::Scope scope(script_state_); ResolveResponseReadyProperty(Response::Create(script_state_, *response)); } @@ -88,6 +91,18 @@ return record_state_ == State::kPending; } +void BackgroundFetchRecord::OnRequestCompleted( + mojom::blink::FetchAPIResponsePtr response) { + if (!response.is_null()) + SetResponseAndUpdateState(response); + else + UpdateState(State::kSettled); +} + +const KURL& BackgroundFetchRecord::ObservedUrl() const { + return request_->url(); +} + void BackgroundFetchRecord::Trace(blink::Visitor* visitor) { visitor->Trace(request_); visitor->Trace(response_ready_property_);
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h b/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h index 979d837..d150009 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h
@@ -9,8 +9,8 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_property.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/core/testing/garbage_collected_script_wrappable.h" #include "third_party/blink/renderer/modules/modules_export.h" -#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" namespace blink { @@ -50,13 +50,16 @@ bool IsRecordPending(); void Trace(blink::Visitor* visitor) override; + void OnRequestCompleted(mojom::blink::FetchAPIResponsePtr response); + const KURL& ObservedUrl() const; + private: using ResponseReadyProperty = ScriptPromiseProperty<Member<BackgroundFetchRecord>, Member<Response>, Member<DOMException>>; - // Resolves a pending |response_read_property_| with |response|, if it's not + // Resolves a pending |response_ready_property_| with |response|, if it's not // null. // If |response| is null, we do nothing if the record isn't final yet. If // |record_state_| is State::kSettled in this case, we reject the promise.
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc index bf9e813..014c7608 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc
@@ -103,6 +103,20 @@ records_available_ = false; } +void BackgroundFetchRegistration::OnRequestCompleted( + mojom::blink::FetchAPIRequestPtr request, + mojom::blink::FetchAPIResponsePtr response) { + for (auto* it = observers_.begin(); it != observers_.end();) { + BackgroundFetchRecord* observer = it->Get(); + if (observer->ObservedUrl() == request->url) { + observer->OnRequestCompleted(response->Clone()); + it = observers_.erase(it); + } else { + it++; + } + } +} + String BackgroundFetchRegistration::id() const { return developer_id_; } @@ -154,9 +168,10 @@ const RequestOrUSVString& request, const CacheQueryOptions* options, ExceptionState& exception_state) { - return MatchImpl( - script_state, base::make_optional<RequestOrUSVString>(request), - Cache::ToQueryParams(options), exception_state, /* match_all = */ false); + return MatchImpl(script_state, + base::make_optional<RequestOrUSVString>(request), + Cache::ToQueryParams(options), exception_state, + /* match_all = */ false); } ScriptPromise BackgroundFetchRegistration::matchAll( @@ -183,8 +198,8 @@ mojom::blink::QueryParamsPtr cache_query_params, ExceptionState& exception_state, bool match_all) { - // TODO(crbug.com/875201): Update this check once we support access to active - // fetches. + // TODO(crbug.com/875201): Update this check once we support access to + // active fetches. if (result_ == mojom::BackgroundFetchResult::UNSET && !RuntimeEnabledFeatures::BackgroundFetchAccessActiveFetchesEnabled()) { return ScriptPromise::RejectWithDOMException( @@ -249,6 +264,11 @@ auto* record = MakeGarbageCollected<BackgroundFetchRecord>(request, script_state); + // If this request is incomplete, enlist this record to receive updates on + // the request. + if (fetch->response.is_null() && !IsAborted()) + observers_.push_back(*record); + UpdateRecord(record, fetch->response); to_return.push_back(record); } @@ -364,9 +384,20 @@ observer_binding_.Close(); } +bool BackgroundFetchRegistration::HasPendingActivity() const { + if (!GetExecutionContext()) + return false; + if (GetExecutionContext()->IsContextDestroyed()) + return false; + + return !observers_.IsEmpty(); +} + void BackgroundFetchRegistration::Trace(Visitor* visitor) { visitor->Trace(registration_); + visitor->Trace(observers_); EventTargetWithInlineData::Trace(visitor); + ActiveScriptWrappable::Trace(visitor); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h index d7213eb6c..4c8b41a 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h
@@ -7,6 +7,7 @@ #include "mojo/public/cpp/bindings/binding.h" #include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom-blink.h" +#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -28,9 +29,11 @@ // access to its properties, options, and enables them to abort the fetch. class BackgroundFetchRegistration final : public EventTargetWithInlineData, + public ActiveScriptWrappable<BackgroundFetchRegistration>, public blink::mojom::blink::BackgroundFetchRegistrationObserver { DEFINE_WRAPPERTYPEINFO(); USING_PRE_FINALIZER(BackgroundFetchRegistration, Dispose); + USING_GARBAGE_COLLECTED_MIXIN(BackgroundFetchRegistration); public: BackgroundFetchRegistration( @@ -63,6 +66,11 @@ mojom::BackgroundFetchFailureReason failure_reason) override; void OnRecordsUnavailable() override; + // Called when the |request| is complete. |response| points to the response + // received, if any. + void OnRequestCompleted(mojom::blink::FetchAPIRequestPtr request, + mojom::blink::FetchAPIResponsePtr response) override; + // Web Exposed attribute defined in the IDL file. Corresponds to the // |developer_id| used elsewhere in the codebase. String id() const; @@ -99,6 +107,9 @@ void Trace(blink::Visitor* visitor) override; + // Keeps the object alive until there are non-zero number of |observers_|. + bool HasPendingActivity() const final; + private: void DidAbort(ScriptPromiseResolver* resolver, mojom::blink::BackgroundFetchError error); @@ -137,6 +148,7 @@ bool records_available_ = true; mojom::BackgroundFetchResult result_; mojom::BackgroundFetchFailureReason failure_reason_; + HeapVector<Member<BackgroundFetchRecord>> observers_; mojo::Binding<blink::mojom::blink::BackgroundFetchRegistrationObserver> observer_binding_;
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.idl b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.idl index bfac3cef..1fd3b46 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.idl +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.idl
@@ -5,7 +5,8 @@ // https://wicg.github.io/background-fetch/#background-fetch-registration [ Exposed=(Window,Worker), - OriginTrialEnabled=BackgroundFetch + OriginTrialEnabled=BackgroundFetch, + ActiveScriptWrappable ] interface BackgroundFetchRegistration : EventTarget { readonly attribute DOMString id; readonly attribute unsigned long long uploadTotal;
diff --git a/third_party/blink/renderer/modules/badging/badge.cc b/third_party/blink/renderer/modules/badging/badge.cc index 2985f63..b7c7ca2 100644 --- a/third_party/blink/renderer/modules/badging/badge.cc +++ b/third_party/blink/renderer/modules/badging/badge.cc
@@ -5,7 +5,6 @@ #include "third_party/blink/renderer/modules/badging/badge.h" #include "services/service_manager/public/cpp/interface_provider.h" -#include "third_party/blink/renderer/bindings/modules/v8/usv_string_or_long.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" @@ -29,14 +28,17 @@ // static void Badge::set(ScriptState* script_state, ExceptionState& exception_state) { - BadgeFromState(script_state)->Set(nullptr, exception_state); + BadgeFromState(script_state)->SetFlag(); } // static void Badge::set(ScriptState* script_state, - USVStringOrLong& contents, + uint64_t content, ExceptionState& exception_state) { - BadgeFromState(script_state)->Set(&contents, exception_state); + if (content == 0) + BadgeFromState(script_state)->Clear(); + else + BadgeFromState(script_state)->SetInteger(content); } // static @@ -44,21 +46,12 @@ BadgeFromState(script_state)->Clear(); } -void Badge::Set(USVStringOrLong* contents, ExceptionState& exception_state) { - if (contents) { - if (contents->IsLong() && contents->GetAsLong() <= 0) { - exception_state.ThrowTypeError("Badge contents should be > 0"); - return; - } - if (contents->IsUSVString() && contents->GetAsUSVString() == "") { - exception_state.ThrowTypeError( - "Badge contents cannot be the empty string"); - return; - } - } - // TODO(estevenson): Add support for sending badge contents to the browser. - // TODO(estevenson): Verify that contents is a single grapheme cluster. - badge_service_->SetBadge(); +void Badge::SetInteger(uint64_t content) { + badge_service_->SetInteger(content); +} + +void Badge::SetFlag() { + badge_service_->SetFlag(); } void Badge::Clear() {
diff --git a/third_party/blink/renderer/modules/badging/badge.h b/third_party/blink/renderer/modules/badging/badge.h index 4054e74..1c53cc3 100644 --- a/third_party/blink/renderer/modules/badging/badge.h +++ b/third_party/blink/renderer/modules/badging/badge.h
@@ -14,7 +14,6 @@ class ExceptionState; class ExecutionContext; class ScriptState; -class USVStringOrLong; class Badge final : public ScriptWrappable, public Supplement<ExecutionContext> { @@ -31,10 +30,11 @@ // Badge IDL interface. static void set(ScriptState*, ExceptionState&); - static void set(ScriptState*, USVStringOrLong&, ExceptionState&); + static void set(ScriptState*, uint64_t content, ExceptionState&); static void clear(ScriptState*); - void Set(USVStringOrLong*, ExceptionState&); + void SetInteger(uint64_t content); + void SetFlag(); void Clear(); void Trace(blink::Visitor*) override;
diff --git a/third_party/blink/renderer/modules/badging/badge.idl b/third_party/blink/renderer/modules/badging/badge.idl index 3c5ec519..dc758d4 100644 --- a/third_party/blink/renderer/modules/badging/badge.idl +++ b/third_party/blink/renderer/modules/badging/badge.idl
@@ -11,6 +11,6 @@ Exposed=Window ] interface Badge { [CallWith=ScriptState, RaisesException] - static void set(optional (USVString or long) contents); + static void set(optional [EnforceRange] unsigned long long contents); [CallWith=ScriptState] static void clear(); };
diff --git a/third_party/blink/renderer/modules/battery/battery_manager.idl b/third_party/blink/renderer/modules/battery/battery_manager.idl index 412eb2d..4343edf 100644 --- a/third_party/blink/renderer/modules/battery/battery_manager.idl +++ b/third_party/blink/renderer/modules/battery/battery_manager.idl
@@ -7,10 +7,10 @@ ActiveScriptWrappable, Exposed=Window ] interface BatteryManager : EventTarget { - readonly attribute boolean charging; - readonly attribute unrestricted double chargingTime; - readonly attribute unrestricted double dischargingTime; - readonly attribute double level; + [HighEntropy, Measure] readonly attribute boolean charging; + [HighEntropy, Measure] readonly attribute unrestricted double chargingTime; + [HighEntropy, Measure] readonly attribute unrestricted double dischargingTime; + [HighEntropy, Measure] readonly attribute double level; attribute EventHandler onchargingchange; attribute EventHandler onchargingtimechange;
diff --git a/third_party/blink/renderer/modules/bluetooth/BUILD.gn b/third_party/blink/renderer/modules/bluetooth/BUILD.gn index 86525de..eb3b1c8 100644 --- a/third_party/blink/renderer/modules/bluetooth/BUILD.gn +++ b/third_party/blink/renderer/modules/bluetooth/BUILD.gn
@@ -8,6 +8,8 @@ sources = [ "bluetooth.cc", "bluetooth.h", + "bluetooth_advertising_event.cc", + "bluetooth_advertising_event.h", "bluetooth_attribute_instance_map.cc", "bluetooth_attribute_instance_map.h", "bluetooth_characteristic_properties.cc", @@ -16,6 +18,10 @@ "bluetooth_device.h", "bluetooth_error.cc", "bluetooth_error.h", + "bluetooth_le_scan.cc", + "bluetooth_le_scan.h", + "bluetooth_manufacturer_data_map.cc", + "bluetooth_manufacturer_data_map.h", "bluetooth_remote_gatt_characteristic.cc", "bluetooth_remote_gatt_characteristic.h", "bluetooth_remote_gatt_descriptor.cc", @@ -26,6 +32,8 @@ "bluetooth_remote_gatt_service.h", "bluetooth_remote_gatt_utils.cc", "bluetooth_remote_gatt_utils.h", + "bluetooth_service_data_map.cc", + "bluetooth_service_data_map.h", "bluetooth_uuid.cc", "bluetooth_uuid.h", "navigator_bluetooth.cc",
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc index 566c3f6..1c5e9d1 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
@@ -6,21 +6,26 @@ #include <memory> #include <utility> -#include "build/build_config.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/document.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/execution_context/execution_context.h" #include "third_party/blink/renderer/core/frame/frame.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/inspector/console_message.h" +#include "third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h" +#include "third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event_init.h" #include "third_party/blink/renderer/modules/bluetooth/bluetooth_device.h" #include "third_party/blink/renderer/modules/bluetooth/bluetooth_error.h" +#include "third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.h" +#include "third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan_options.h" +#include "third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.h" #include "third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h" +#include "third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.h" #include "third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.h" #include "third_party/blink/renderer/modules/bluetooth/request_device_options.h" #include "third_party/blink/renderer/platform/wtf/functional.h" @@ -138,12 +143,13 @@ mojom::blink::WebBluetoothResult result, mojom::blink::WebBluetoothDevicePtr device) { if (!resolver->GetExecutionContext() || - resolver->GetExecutionContext()->IsContextDestroyed()) + resolver->GetExecutionContext()->IsContextDestroyed()) { return; + } if (result == mojom::blink::WebBluetoothResult::SUCCESS) { - BluetoothDevice* bluetooth_device = - GetBluetoothDeviceRepresentingDevice(std::move(device), resolver); + BluetoothDevice* bluetooth_device = GetBluetoothDeviceRepresentingDevice( + std::move(device), resolver->GetExecutionContext()); resolver->Resolve(bluetooth_device); } else { resolver->Reject(BluetoothError::CreateDOMException(result)); @@ -216,20 +222,147 @@ return promise; } -void Bluetooth::Trace(blink::Visitor* visitor) { - visitor->Trace(device_instance_map_); - ScriptWrappable::Trace(visitor); +void Bluetooth::RequestScanningCallback( + ScriptPromiseResolver* resolver, + mojo::BindingId id, + mojom::blink::WebBluetoothResult result) { + if (!resolver->GetExecutionContext() || + resolver->GetExecutionContext()->IsContextDestroyed()) { + return; + } + + if (result == mojom::blink::WebBluetoothResult::SUCCESS) { + auto* scan = BluetoothLEScan::Create(id, this, + /*keep_repeated_device=*/true, + /*accept_all_advertisements=*/true); + resolver->Resolve(scan); + } else { + resolver->Reject(BluetoothError::CreateDOMException(result)); + } } -Bluetooth::Bluetooth() = default; +// https://webbluetoothcg.github.io/web-bluetooth/scanning.html#dom-bluetooth-requestlescan +ScriptPromise Bluetooth::requestLEScan(ScriptState* script_state, + const BluetoothLEScanOptions* options, + ExceptionState& exception_state) { + ExecutionContext* context = ExecutionContext::From(script_state); + + // Remind developers when they are using Web Bluetooth on unsupported + // platforms. + context->AddConsoleMessage(ConsoleMessage::Create( + kJSMessageSource, kInfoMessageLevel, + "Web Bluetooth Scanning is experimental on this platform. See " + "https://github.com/WebBluetoothCG/web-bluetooth/blob/gh-pages/" + "implementation-status.md")); + + CHECK(context->IsSecureContext()); + + // If the algorithm is not allowed to show a popup, reject promise with a + // SecurityError and abort these steps. + auto& doc = *To<Document>(context); + if (!LocalFrame::HasTransientUserActivation(doc.GetFrame())) { + return ScriptPromise::RejectWithDOMException( + script_state, + DOMException::Create( + DOMExceptionCode::kSecurityError, + "Must be handling a user gesture to show a permission request.")); + } + + if (!service_) { + LocalFrame* frame = doc.GetFrame(); + if (frame) { + frame->GetInterfaceProvider().GetInterface(mojo::MakeRequest(&service_)); + } + } + + if (!service_) { + return ScriptPromise::RejectWithDOMException( + script_state, + DOMException::Create(DOMExceptionCode::kNotSupportedError)); + } + + // TODO(dougt) deal with |options| here. + + // Record the eTLD+1 of the frame using the API. + Platform::Current()->RecordRapporURL("Bluetooth.APIUsage.Origin", doc.Url()); + + // Subsequent steps are handled in the browser process. + ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); + ScriptPromise promise = resolver->Promise(); + + mojom::blink::WebBluetoothScanClientAssociatedPtrInfo client; + mojo::BindingId id = + client_bindings_.AddBinding(this, mojo::MakeRequest(&client)); + + service_->RequestScanningStart( + std::move(client), + WTF::Bind(&Bluetooth::RequestScanningCallback, WrapPersistent(this), + WrapPersistent(resolver), id)); + + return promise; +} + +void Bluetooth::ScanEvent(mojom::blink::WebBluetoothScanResultPtr result) { + ExecutionContext* content = ContextLifecycleObserver::GetExecutionContext(); + BluetoothDevice* bluetooth_device = + GetBluetoothDeviceRepresentingDevice(std::move(result->device), content); + + HeapVector<blink::StringOrUnsignedLong> uuids; + for (const String& uuid : result->uuids) { + StringOrUnsignedLong value; + value.SetString(uuid); + uuids.push_back(value); + } + + auto* manufacturer_data = MakeGarbageCollected<BluetoothManufacturerDataMap>( + result->manufacturer_data); + auto* service_data = + MakeGarbageCollected<BluetoothServiceDataMap>(result->service_data); + + auto* event = BluetoothAdvertisingEvent::Create( + event_type_names::kAdvertisementreceived, bluetooth_device, result->name, + uuids, result->appearance, result->tx_power, result->rssi, + manufacturer_data, service_data); + DispatchEvent(*event); +} + +void Bluetooth::CancelScan(mojo::BindingId id) { + client_bindings_.RemoveBinding(id); +} + +const WTF::AtomicString& Bluetooth::InterfaceName() const { + return event_type_names::kAdvertisementreceived; +} + +ExecutionContext* Bluetooth::GetExecutionContext() const { + return ContextLifecycleObserver::GetExecutionContext(); +} + +void Bluetooth::ContextDestroyed(ExecutionContext*) { + Dispose(); +} + +void Bluetooth::Dispose() { + client_bindings_.CloseAllBindings(); +} + +void Bluetooth::Trace(blink::Visitor* visitor) { + visitor->Trace(device_instance_map_); + EventTargetWithInlineData::Trace(visitor); + ContextLifecycleObserver::Trace(visitor); +} + +Bluetooth::Bluetooth(ExecutionContext* context) + : ContextLifecycleObserver(context) {} BluetoothDevice* Bluetooth::GetBluetoothDeviceRepresentingDevice( mojom::blink::WebBluetoothDevicePtr device_ptr, - ScriptPromiseResolver* resolver) { - WTF::String id = device_ptr->id; + ExecutionContext* context) { + String& id = device_ptr->id; BluetoothDevice* device = device_instance_map_.at(id); if (!device) { - device = BluetoothDevice::Take(resolver, std::move(device_ptr), this); + device = MakeGarbageCollected<BluetoothDevice>(context, + std::move(device_ptr), this); auto result = device_instance_map_.insert(id, device); DCHECK(result.is_new_entry); }
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth.h b/third_party/blink/renderer/modules/bluetooth/bluetooth.h index 0eb0092..da428583 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth.h +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth.h
@@ -14,42 +14,79 @@ namespace blink { +class BluetoothLEScanOptions; class RequestDeviceOptions; class ScriptPromise; class ScriptState; -class Bluetooth final : public ScriptWrappable { +class Bluetooth final : public EventTargetWithInlineData, + public ContextLifecycleObserver, + public mojom::blink::WebBluetoothScanClient { + USING_PRE_FINALIZER(Bluetooth, Dispose); DEFINE_WRAPPERTYPEINFO(); + USING_GARBAGE_COLLECTED_MIXIN(Bluetooth); public: - static Bluetooth* Create() { return MakeGarbageCollected<Bluetooth>(); } + static Bluetooth* Create(ExecutionContext* context) { + return MakeGarbageCollected<Bluetooth>(context); + } - Bluetooth(); + explicit Bluetooth(ExecutionContext*); // IDL exposed interface: ScriptPromise requestDevice(ScriptState*, const RequestDeviceOptions*, ExceptionState&); + ScriptPromise requestLEScan(ScriptState*, + const BluetoothLEScanOptions*, + ExceptionState&); + mojom::blink::WebBluetoothService* Service() { return service_.get(); } + // mojom::blink::WebBluetoothScanClient: + void ScanEvent(mojom::blink::WebBluetoothScanResultPtr result) override; + + // EventTarget methods: + const AtomicString& InterfaceName() const override; + ExecutionContext* GetExecutionContext() const override; + // Interface required by Garbage Collection: void Trace(blink::Visitor*) override; + // ContextLifecycleObserver interface. + void ContextDestroyed(ExecutionContext*) override; + + // USING_PRE_FINALIZER interface. + // Called before the object gets garbage collected. + void Dispose(); + + DEFINE_ATTRIBUTE_EVENT_LISTENER(advertisementreceived, + kAdvertisementreceived); + + void CancelScan(mojo::BindingId); + private: BluetoothDevice* GetBluetoothDeviceRepresentingDevice( mojom::blink::WebBluetoothDevicePtr, - ScriptPromiseResolver*); + ExecutionContext*); void RequestDeviceCallback(ScriptPromiseResolver*, mojom::blink::WebBluetoothResult, mojom::blink::WebBluetoothDevicePtr); + void RequestScanningCallback(ScriptPromiseResolver*, + mojo::BindingId id, + mojom::blink::WebBluetoothResult); + // Map of device ids to BluetoothDevice objects. // Ensures only one BluetoothDevice instance represents each // Bluetooth device inside a single global object. HeapHashMap<String, Member<BluetoothDevice>> device_instance_map_; + mojo::AssociatedBindingSet<mojom::blink::WebBluetoothScanClient> + client_bindings_; + mojom::blink::WebBluetoothServicePtr service_; };
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth.idl b/third_party/blink/renderer/modules/bluetooth/bluetooth.idl index ade4e8d..3e2272c9 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth.idl +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth.idl
@@ -7,6 +7,12 @@ [ RuntimeEnabled=WebBluetooth, SecureContext -] interface Bluetooth { +] interface Bluetooth : EventTarget { [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRequestDevice] Promise<BluetoothDevice> requestDevice (optional RequestDeviceOptions options); -}; + + // https://webbluetoothcg.github.io/web-bluetooth/scanning.html#dom-bluetooth-requestlescan + [RuntimeEnabled=WebBluetoothScanning, CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRequestScan] + Promise<BluetoothLEScan> requestLEScan (optional BluetoothLEScanOptions options); + + [RuntimeEnabled=WebBluetoothScanning] attribute EventHandler onadvertisementreceived; +};
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc new file mode 100644 index 0000000..ec42a95 --- /dev/null +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc
@@ -0,0 +1,100 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h" +#include "third_party/blink/renderer/bindings/modules/v8/string_or_unsigned_long.h" +#include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/core/event_type_names.h" +#include "third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event_init.h" +#include "third_party/blink/renderer/modules/bluetooth/bluetooth_device.h" +#include "third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.h" +#include "third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.h" + +namespace blink { + +BluetoothAdvertisingEvent::BluetoothAdvertisingEvent( + const AtomicString& event_type, + const BluetoothAdvertisingEventInit* initializer) + : Event(event_type, initializer), + device_(initializer->device()), + name_(initializer->name()), + uuids_(initializer->uuids()), + appearance_(initializer->hasAppearance() ? initializer->appearance() : 0), + txPower_(initializer->hasTxPower() ? initializer->txPower() : 0), + rssi_(initializer->hasRssi() ? initializer->rssi() : 0), + manufacturer_data_map_(initializer->manufacturerData()), + service_data_map_(initializer->serviceData()) {} + +BluetoothAdvertisingEvent::BluetoothAdvertisingEvent( + const AtomicString& event_type, + BluetoothDevice* device, + const String& name, + const HeapVector<StringOrUnsignedLong>& uuids, + short appearance, + int8_t txPower, + int8_t rssi, + BluetoothManufacturerDataMap* manufacturerData, + BluetoothServiceDataMap* serviceData) + : Event(event_type, Bubbles::kYes, Cancelable::kYes), + device_(std::move(device)), + name_(name), + uuids_(uuids), + appearance_(appearance), + txPower_(txPower), + rssi_(rssi), + manufacturer_data_map_(manufacturerData), + service_data_map_(serviceData) {} + +BluetoothAdvertisingEvent::~BluetoothAdvertisingEvent() {} + +void BluetoothAdvertisingEvent::Trace(blink::Visitor* visitor) { + visitor->Trace(device_); + visitor->Trace(uuids_); + visitor->Trace(manufacturer_data_map_); + visitor->Trace(service_data_map_); + Event::Trace(visitor); +} + +const AtomicString& BluetoothAdvertisingEvent::InterfaceName() const { + return event_type_names::kAdvertisementreceived; +} + +BluetoothDevice* BluetoothAdvertisingEvent::device() const { + return device_; +}; + +const String& BluetoothAdvertisingEvent::name() const { + return name_; +} + +const HeapVector<StringOrUnsignedLong>& BluetoothAdvertisingEvent::uuids() + const { + return uuids_; +} + +short BluetoothAdvertisingEvent::appearance(bool& is_null) const { + is_null = !appearance_.has_value(); + return appearance_.value_or(0); +} + +int8_t BluetoothAdvertisingEvent::txPower(bool& is_null) const { + is_null = !txPower_.has_value(); + return txPower_.value_or(0); +} + +int8_t BluetoothAdvertisingEvent::rssi(bool& is_null) const { + is_null = !rssi_.has_value(); + return rssi_.value_or(0); +} + +BluetoothManufacturerDataMap* BluetoothAdvertisingEvent::manufacturerData() + const { + return manufacturer_data_map_; +} + +BluetoothServiceDataMap* BluetoothAdvertisingEvent::serviceData() const { + return service_data_map_; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h b/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h new file mode 100644 index 0000000..cc1e0cf --- /dev/null +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h
@@ -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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_ADVERTISING_EVENT_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_ADVERTISING_EVENT_H_ + +#include "third_party/blink/renderer/core/dom/events/event.h" + +namespace blink { + +class BluetoothDevice; +class BluetoothAdvertisingEventInit; +class BluetoothManufacturerDataMap; +class BluetoothServiceDataMap; +class StringOrUnsignedLong; + +class BluetoothAdvertisingEvent final : public Event { + DEFINE_WRAPPERTYPEINFO(); + + public: + static BluetoothAdvertisingEvent* Create( + const AtomicString& event_type, + const BluetoothAdvertisingEventInit* initializer) { + return MakeGarbageCollected<BluetoothAdvertisingEvent>(event_type, + initializer); + } + + static BluetoothAdvertisingEvent* Create( + const AtomicString& event_type, + BluetoothDevice* device, + const String& name, + const HeapVector<StringOrUnsignedLong>& uuids, + short appearance, + int8_t txPower, + int8_t rssi, + BluetoothManufacturerDataMap* manufacturer_data_map, + BluetoothServiceDataMap* service_data_map) { + return MakeGarbageCollected<BluetoothAdvertisingEvent>( + event_type, device, name, uuids, appearance, txPower, rssi, + manufacturer_data_map, service_data_map); + } + + BluetoothAdvertisingEvent(const AtomicString& event_type, + const BluetoothAdvertisingEventInit* initializer); + + BluetoothAdvertisingEvent(const AtomicString& event_type, + BluetoothDevice* device, + const String& name, + const HeapVector<StringOrUnsignedLong>& uuids, + short appearance, + int8_t txPower, + int8_t rssi, + BluetoothManufacturerDataMap* manufacturer_data_map, + BluetoothServiceDataMap* service_data_map); + + ~BluetoothAdvertisingEvent() override; + + void Trace(blink::Visitor*) override; + + const AtomicString& InterfaceName() const override; + + BluetoothDevice* device() const; + const String& name() const; + const HeapVector<StringOrUnsignedLong>& uuids() const; + short appearance(bool& is_null) const; + int8_t txPower(bool& is_null) const; + int8_t rssi(bool& is_null) const; + BluetoothManufacturerDataMap* manufacturerData() const; + BluetoothServiceDataMap* serviceData() const; + + private: + Member<BluetoothDevice> device_; + String name_; + HeapVector<StringOrUnsignedLong> uuids_; + base::Optional<short> appearance_; + base::Optional<int8_t> txPower_; + base::Optional<int8_t> rssi_; + const Member<BluetoothManufacturerDataMap> manufacturer_data_map_; + const Member<BluetoothServiceDataMap> service_data_map_; +}; + +} // namespace blink + +#endif
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.idl b/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.idl new file mode 100644 index 0000000..1cd2994 --- /dev/null +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.idl
@@ -0,0 +1,20 @@ +// 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. + +// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothadvertisingevent + +[ + RuntimeEnabled=WebBluetoothScanning, + SecureContext +] interface BluetoothAdvertisingEvent : Event { + + 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; + readonly attribute BluetoothManufacturerDataMap manufacturerData; + readonly attribute BluetoothServiceDataMap serviceData; +};
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event_init.idl b/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event_init.idl new file mode 100644 index 0000000..0cb5856 --- /dev/null +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event_init.idl
@@ -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. + +// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothadvertisingevent + +dictionary BluetoothAdvertisingEventInit : EventInit { + required BluetoothDevice device; + sequence<(DOMString or unsigned long)> uuids; + DOMString name; + unsigned short appearance; + byte txPower; + byte rssi; + BluetoothManufacturerDataMap manufacturerData; + BluetoothServiceDataMap serviceData; +};
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_device.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_device.cc index 0788622..d69d3a2 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth_device.cc +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_device.cc
@@ -30,15 +30,6 @@ gatt_(BluetoothRemoteGATTServer::Create(context, this)), bluetooth_(bluetooth) {} -// static -BluetoothDevice* BluetoothDevice::Take( - ScriptPromiseResolver* resolver, - mojom::blink::WebBluetoothDevicePtr device, - Bluetooth* bluetooth) { - return MakeGarbageCollected<BluetoothDevice>(resolver->GetExecutionContext(), - std::move(device), bluetooth); -} - BluetoothRemoteGATTService* BluetoothDevice::GetOrCreateRemoteGATTService( mojom::blink::WebBluetoothRemoteGATTServicePtr service, bool is_primary,
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h b/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h index e0ad24c3..41d8b8d 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h
@@ -22,7 +22,6 @@ class BluetoothRemoteGATTDescriptor; class BluetoothRemoteGATTServer; class BluetoothRemoteGATTService; -class ScriptPromiseResolver; // BluetoothDevice represents a physical bluetooth device in the DOM. See IDL. // @@ -40,11 +39,6 @@ mojom::blink::WebBluetoothDevicePtr, Bluetooth*); - // Interface required by CallbackPromiseAdapter: - static BluetoothDevice* Take(ScriptPromiseResolver*, - mojom::blink::WebBluetoothDevicePtr, - Bluetooth*); - BluetoothRemoteGATTService* GetOrCreateRemoteGATTService( mojom::blink::WebBluetoothRemoteGATTServicePtr, bool is_primary,
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.cc new file mode 100644 index 0000000..8e87c34 --- /dev/null +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.cc
@@ -0,0 +1,55 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.h" + +namespace blink { + +BluetoothLEScan* BluetoothLEScan::Create(mojo::BindingId id, + Bluetooth* bluetooth, + bool keep_repeated_devices, + bool accept_all_advertisements) { + return MakeGarbageCollected<BluetoothLEScan>( + id, bluetooth, keep_repeated_devices, accept_all_advertisements); +} + +BluetoothLEScan::BluetoothLEScan(mojo::BindingId id, + Bluetooth* bluetooth, + bool keep_repeated_devices, + bool accept_all_advertisements) + : id_(id), + bluetooth_(bluetooth), + keep_repeated_devices_(keep_repeated_devices), + accept_all_advertisements_(accept_all_advertisements) {} + +const HeapVector<Member<BluetoothLEScanFilterInit>>& BluetoothLEScan::filters() + const { + // TODO(dougt) We need to support filters. + return filters_; +} + +bool BluetoothLEScan::keepRepeatedDevices() const { + return keep_repeated_devices_; +} +bool BluetoothLEScan::acceptAllAdvertisements() const { + return accept_all_advertisements_; +} + +bool BluetoothLEScan::active() const { + return is_active_; +} + +bool BluetoothLEScan::stop() { + bluetooth_->CancelScan(id_); + is_active_ = false; + return true; +} + +void BluetoothLEScan::Trace(blink::Visitor* visitor) { + visitor->Trace(filters_); + visitor->Trace(bluetooth_); + ScriptWrappable::Trace(visitor); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.h b/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.h new file mode 100644 index 0000000..9302b36 --- /dev/null +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.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 THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_LE_SCAN_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_LE_SCAN_H_ + +#include "third_party/blink/renderer/modules/bluetooth/bluetooth.h" +#include "third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan_filter_init.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" + +namespace blink { + +class BluetoothLEScan final : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + static BluetoothLEScan* Create(mojo::BindingId, + Bluetooth*, + bool keep_repeated_devices, + bool accept_all_advertisements); + + BluetoothLEScan(mojo::BindingId, + Bluetooth*, + bool keep_repeated_devices, + bool accept_all_advertisements); + + // IDL exposed interface: + const HeapVector<Member<BluetoothLEScanFilterInit>>& filters() const; + bool keepRepeatedDevices() const; + bool acceptAllAdvertisements() const; + bool active() const; + bool stop(); + + // Interface required by garbage collection. + void Trace(blink::Visitor*) override; + + private: + mojo::BindingId id_; + HeapVector<Member<BluetoothLEScanFilterInit>> filters_; + Member<Bluetooth> bluetooth_; + const bool keep_repeated_devices_; + const bool accept_all_advertisements_; + bool is_active_ = true; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_LE_SCAN_H_
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.idl b/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.idl new file mode 100644 index 0000000..7ffb1c3 --- /dev/null +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.idl
@@ -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. + +// https://webbluetoothcg.github.io/web-bluetooth/scanning.html#bluetoothlescan + +[ + RuntimeEnabled=WebBluetoothScanning, + SecureContext +] interface BluetoothLEScan { + readonly attribute FrozenArray<BluetoothLEScanFilter> filters; + readonly attribute boolean keepRepeatedDevices; + readonly attribute boolean acceptAllAdvertisements; + readonly attribute boolean active; + void stop(); +};
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan_options.idl b/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan_options.idl new file mode 100644 index 0000000..8d6c500a --- /dev/null +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan_options.idl
@@ -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. + +// https://webbluetoothcg.github.io/web-bluetooth/scanning.html#dictdef-bluetoothlescanoptions + +dictionary BluetoothLEScanOptions { + sequence<BluetoothLEScanFilterInit> filters; + boolean keepRepeatedDevices = false; + boolean acceptAllAdvertisements = false; +};
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.cc new file mode 100644 index 0000000..e4af2f6c --- /dev/null +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.cc
@@ -0,0 +1,72 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.h" + +#include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h" +#include "third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_utils.h" + +namespace blink { + +class BluetoothManufacturerDataMapIterationSource final + : public PairIterable<unsigned short, + Member<DOMDataView>>::IterationSource { + public: + explicit BluetoothManufacturerDataMapIterationSource( + const BluetoothManufacturerDataMap& map) + : map_(map), iterator_(map_->Map().begin()) {} + + bool Next(ScriptState* script_state, + unsigned short& map_key, + Member<DOMDataView>& map_value, + ExceptionState&) override { + if (iterator_ == map_->Map().end()) + return false; + map_key = iterator_->key; + map_value = + BluetoothRemoteGATTUtils::ConvertWTFVectorToDataView(iterator_->value); + ++iterator_; + return true; + } + + void Trace(blink::Visitor* visitor) override { + visitor->Trace(map_); + PairIterable<unsigned short, Member<DOMDataView>>::IterationSource::Trace( + visitor); + } + + private: + // Needs to be kept alive while we're iterating over it. + const Member<const BluetoothManufacturerDataMap> map_; + BluetoothManufacturerDataMap::MapType::const_iterator iterator_; +}; + +BluetoothManufacturerDataMap::BluetoothManufacturerDataMap( + const BluetoothManufacturerDataMap::MapType& map) + : parameter_map_(map) {} + +BluetoothManufacturerDataMap::~BluetoothManufacturerDataMap() {} + +PairIterable<unsigned short, Member<DOMDataView>>::IterationSource* +BluetoothManufacturerDataMap::StartIteration(ScriptState*, ExceptionState&) { + return MakeGarbageCollected<BluetoothManufacturerDataMapIterationSource>( + *this); +} + +bool BluetoothManufacturerDataMap::GetMapEntry(ScriptState*, + const unsigned short& key, + Member<DOMDataView>& value, + ExceptionState&) { + auto it = parameter_map_.find(key); + if (it == parameter_map_.end()) + return false; + + DOMDataView* dom_data_view = + BluetoothRemoteGATTUtils::ConvertWTFVectorToDataView(it->value); + + value = dom_data_view; + return true; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.h b/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.h new file mode 100644 index 0000000..a4eeeaf --- /dev/null +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.h
@@ -0,0 +1,46 @@ +// 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_MODULES_BLUETOOTH_BLUETOOTH_MANUFACTURER_DATA_MAP_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_MANUFACTURER_DATA_MAP_H_ + +#include "third_party/blink/renderer/bindings/core/v8/maplike.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" +#include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/heap/garbage_collected.h" + +namespace blink { + +class BluetoothManufacturerDataMap final + : public ScriptWrappable, + public Maplike<unsigned short, Member<DOMDataView>> { + DEFINE_WRAPPERTYPEINFO(); + + public: + using MapType = HashMap<unsigned short, WTF::Vector<unsigned char>>; + + explicit BluetoothManufacturerDataMap(const MapType&); + + ~BluetoothManufacturerDataMap() override; + + const MapType& Map() const { return parameter_map_; } + + // IDL attributes / methods + uint32_t size() const { return parameter_map_.size(); } + + private: + PairIterable<unsigned short, Member<DOMDataView>>::IterationSource* + StartIteration(ScriptState*, ExceptionState&) override; + bool GetMapEntry(ScriptState*, + const unsigned short& key, + Member<DOMDataView>&, + ExceptionState&) override; + + const MapType parameter_map_; +}; + +} // namespace blink + +#endif
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.idl b/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.idl new file mode 100644 index 0000000..78aaa1c --- /dev/null +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.idl
@@ -0,0 +1,10 @@ +// 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. + +// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothadvertisingevent + +[RuntimeEnabled=WebBluetoothScanning, SecureContext] +interface BluetoothManufacturerDataMap { + readonly maplike<unsigned short, DataView>; +};
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.cc new file mode 100644 index 0000000..e0c3fea --- /dev/null +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.cc
@@ -0,0 +1,68 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.h" + +#include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h" +#include "third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_utils.h" + +namespace blink { + +class BluetoothServiceDataMapIterationSource final + : public PairIterable<String, Member<DOMDataView>>::IterationSource { + public: + BluetoothServiceDataMapIterationSource(const BluetoothServiceDataMap& map) + : map_(map), iterator_(map_->Map().begin()) {} + + bool Next(ScriptState* script_state, + String& map_key, + Member<DOMDataView>& map_value, + ExceptionState&) override { + if (iterator_ == map_->Map().end()) + return false; + map_key = iterator_->key; + map_value = + BluetoothRemoteGATTUtils::ConvertWTFVectorToDataView(iterator_->value); + ++iterator_; + return true; + } + + void Trace(blink::Visitor* visitor) override { + visitor->Trace(map_); + PairIterable<String, Member<DOMDataView>>::IterationSource::Trace(visitor); + } + + private: + // Needs to be kept alive while we're iterating over it. + const Member<const BluetoothServiceDataMap> map_; + BluetoothServiceDataMap::MapType::const_iterator iterator_; +}; + +BluetoothServiceDataMap::BluetoothServiceDataMap( + const BluetoothServiceDataMap::MapType& map) + : parameter_map_(map) {} + +BluetoothServiceDataMap::~BluetoothServiceDataMap() {} + +PairIterable<String, Member<DOMDataView>>::IterationSource* +BluetoothServiceDataMap::StartIteration(ScriptState*, ExceptionState&) { + return MakeGarbageCollected<BluetoothServiceDataMapIterationSource>(*this); +} + +bool BluetoothServiceDataMap::GetMapEntry(ScriptState*, + const String& key, + Member<DOMDataView>& value, + ExceptionState&) { + auto it = parameter_map_.find(key); + if (it == parameter_map_.end()) + return false; + + DOMDataView* dom_data_view = + BluetoothRemoteGATTUtils::ConvertWTFVectorToDataView(it->value); + + value = dom_data_view; + return true; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.h b/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.h new file mode 100644 index 0000000..42d2c5d --- /dev/null +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.h
@@ -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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_SERVICE_DATA_MAP_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_SERVICE_DATA_MAP_H_ + +#include "third_party/blink/renderer/bindings/core/v8/maplike.h" +#include "third_party/blink/renderer/bindings/modules/v8/string_or_unsigned_long.h" +#include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/heap/garbage_collected.h" + +namespace blink { + +class BluetoothServiceDataMap final + : public ScriptWrappable, + public Maplike<String, Member<DOMDataView>> { + DEFINE_WRAPPERTYPEINFO(); + + public: + using MapType = HashMap<String, WTF::Vector<uint8_t>>; + + explicit BluetoothServiceDataMap(const MapType&); + + ~BluetoothServiceDataMap() override; + + const MapType& Map() const { return parameter_map_; } + + // IDL attributes / methods + uint32_t size() const { return parameter_map_.size(); } + + private: + PairIterable<String, Member<DOMDataView>>::IterationSource* StartIteration( + ScriptState*, + ExceptionState&) override; + bool GetMapEntry(ScriptState*, + const String& key, + Member<DOMDataView>&, + ExceptionState&) override; + + const MapType parameter_map_; +}; + +} // namespace blink + +#endif
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.idl b/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.idl new file mode 100644 index 0000000..6be9244 --- /dev/null +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.idl
@@ -0,0 +1,10 @@ +// 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. + +// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothadvertisingevent + +[RuntimeEnabled=WebBluetoothScanning, SecureContext] +interface BluetoothServiceDataMap { + readonly maplike<UUID, DataView>; +}; \ No newline at end of file
diff --git a/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc b/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc index 207382b..74a31c5 100644 --- a/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc +++ b/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc
@@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/navigator.h" #include "third_party/blink/renderer/modules/bluetooth/bluetooth.h" @@ -24,8 +26,14 @@ } Bluetooth* NavigatorBluetooth::bluetooth() { - if (!bluetooth_) - bluetooth_ = Bluetooth::Create(); + if (bluetooth_) + return bluetooth_.Get(); + + if (!GetSupplementable()->GetFrame()) + return nullptr; + + bluetooth_ = Bluetooth::Create( + GetSupplementable()->GetFrame()->GetDocument()->GetExecutionContext()); return bluetooth_.Get(); }
diff --git a/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc b/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc index 9e1fa49cc..96bd4952 100644 --- a/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc +++ b/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc
@@ -251,8 +251,8 @@ nullptr /* body */, request->referrer.Clone(), request->credentials_mode, request->cache_mode, request->redirect_mode, request->integrity, request->priority, - request->fetch_window_id, request->keepalive, request->client_id, - request->is_reload, request->is_history_navigation); + request->fetch_window_id, request->keepalive, request->is_reload, + request->is_history_navigation); cache_ptr_->Match(std::move(request), mojom::blink::QueryParams::New(), WTF::Bind( [](scoped_refptr<ResponsesAccumulator> accumulator,
diff --git a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl index b9a3f6e7f..b53ed13 100644 --- a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl +++ b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl
@@ -60,15 +60,15 @@ void stroke(Path2D path); void clip(); void clip(Path2D path); - boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasFillRule winding); - boolean isPointInPath(Path2D path, unrestricted double x, unrestricted double y, optional CanvasFillRule winding); - boolean isPointInStroke(unrestricted double x, unrestricted double y); - boolean isPointInStroke(Path2D path, unrestricted double x, unrestricted double y); + [HighEntropy, MeasureAs=OffscreenCanvasIsPointInPath] boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasFillRule winding); + [HighEntropy, MeasureAs=OffscreenCanvasIsPointInPath] boolean isPointInPath(Path2D path, unrestricted double x, unrestricted double y, optional CanvasFillRule winding); + [HighEntropy, MeasureAs=OffscreenCanvasIsPointInStroke] boolean isPointInStroke(unrestricted double x, unrestricted double y); + [HighEntropy, MeasureAs=OffscreenCanvasIsPointInStroke] boolean isPointInStroke(Path2D path, unrestricted double x, unrestricted double y); // text (see also the CanvasDrawingStyles interface) void fillText(DOMString text, unrestricted double x, unrestricted double y, optional unrestricted double maxWidth); void strokeText(DOMString text, unrestricted double x, unrestricted double y, optional unrestricted double maxWidth); - TextMetrics measureText(DOMString text); + [HighEntropy, MeasureAs=OffscreenCanvasMeasureText] TextMetrics measureText(DOMString text); // drawing images [CallWith=ScriptState, RaisesException] void drawImage(CanvasImageSource image, unrestricted double x, unrestricted double y); @@ -78,7 +78,7 @@ // pixel manipulation [RaisesException] ImageData createImageData(ImageData imagedata); [RaisesException] ImageData createImageData(long sw, long sh); - [RaisesException] ImageData getImageData(long sx, long sy, long sw, long sh); + [HighEntropy, MeasureAs=OffscreenCanvasGetImageData, RaisesException] ImageData getImageData(long sx, long sy, long sw, long sh); [RaisesException] void putImageData(ImageData imagedata, long dx, long dy); [RaisesException] void putImageData(ImageData imagedata, long dx, long dy, long dirtyX, long dirtyY, long dirtyWidth, long dirtyHeight);
diff --git a/third_party/blink/renderer/modules/clipboard/OWNERS b/third_party/blink/renderer/modules/clipboard/OWNERS new file mode 100644 index 0000000..d637b215 --- /dev/null +++ b/third_party/blink/renderer/modules/clipboard/OWNERS
@@ -0,0 +1,6 @@ +garykac@chromium.org +pwnall@chromium.org +jsbell@chromium.org + +# TEAM: storage-dev@chromium.org +# COMPONENT: Blink>DataTransfer
diff --git a/third_party/blink/renderer/modules/cookie_store/cookie_store.h b/third_party/blink/renderer/modules/cookie_store/cookie_store.h index 26f28a5b9..ef8204a 100644 --- a/third_party/blink/renderer/modules/cookie_store/cookie_store.h +++ b/third_party/blink/renderer/modules/cookie_store/cookie_store.h
@@ -81,7 +81,7 @@ ContextLifecycleObserver::Trace(visitor); } - // ActiveScriptWrappable + // ContextLifecycleObserver void ContextDestroyed(ExecutionContext*) override; // EventTargetWithInlineData
diff --git a/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc b/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc index 19fa7db..fee856ff 100644 --- a/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc +++ b/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
@@ -622,7 +622,16 @@ auto mojo_options = MojoPublicKeyCredentialCreationOptions::From(options->publicKey()); - if (mojo_options) { + if (!mojo_options) { + resolver->Reject(DOMException::Create( + DOMExceptionCode::kNotSupportedError, + "Required parameters missing in `options.publicKey`.")); + } else if (mojo_options->user->id.size() > 64) { + // https://www.w3.org/TR/webauthn/#user-handle + v8::Isolate* isolate = resolver->GetScriptState()->GetIsolate(); + resolver->Reject(V8ThrowException::CreateTypeError( + isolate, "User handle exceeds 64 bytes.")); + } else { if (!mojo_options->relying_party->id) { mojo_options->relying_party->id = resolver->GetFrame() ->GetSecurityContext() @@ -636,10 +645,6 @@ WTF::Bind( &OnMakePublicKeyCredentialComplete, WTF::Passed(std::make_unique<ScopedPromiseResolver>(resolver)))); - } else { - resolver->Reject(DOMException::Create( - DOMExceptionCode::kNotSupportedError, - "Required parameters missing in `options.publicKey`.")); } }
diff --git a/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl b/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl index e7f43a5a..a9a9f03 100644 --- a/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl +++ b/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl
@@ -58,10 +58,10 @@ void clip(optional CanvasFillRule winding); void clip(Path2D path, optional CanvasFillRule winding); - boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasFillRule winding); - boolean isPointInPath(Path2D path, unrestricted double x, unrestricted double y, optional CanvasFillRule winding); - boolean isPointInStroke(unrestricted double x, unrestricted double y); - boolean isPointInStroke(Path2D path, unrestricted double x, unrestricted double y); + [HighEntropy, Measure] boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasFillRule winding); + [HighEntropy, Measure] boolean isPointInPath(Path2D path, unrestricted double x, unrestricted double y, optional CanvasFillRule winding); + [HighEntropy, Measure] boolean isPointInStroke(unrestricted double x, unrestricted double y); + [HighEntropy, Measure] boolean isPointInStroke(Path2D path, unrestricted double x, unrestricted double y); // drawing images [CallWith=ScriptState, RaisesException] void drawImage(CanvasImageSource image, unrestricted double x, unrestricted double y);
diff --git a/third_party/blink/renderer/modules/event_target_modules_names.json5 b/third_party/blink/renderer/modules/event_target_modules_names.json5 index 3f5aec4..e2ef962 100644 --- a/third_party/blink/renderer/modules/event_target_modules_names.json5 +++ b/third_party/blink/renderer/modules/event_target_modules_names.json5
@@ -10,6 +10,7 @@ data: [ "BackgroundFetchRegistration", "BatteryManager", + "Bluetooth", "BluetoothDevice", "BluetoothRemoteGATTCharacteristic", "CookieStore",
diff --git a/third_party/blink/renderer/modules/keyboard/keyboard.idl b/third_party/blink/renderer/modules/keyboard/keyboard.idl index 86832c9..6e2bb694 100644 --- a/third_party/blink/renderer/modules/keyboard/keyboard.idl +++ b/third_party/blink/renderer/modules/keyboard/keyboard.idl
@@ -17,6 +17,7 @@ // Keyboard Map specification: https://wicg.github.io/keyboard-map/ [CallWith=ScriptState, + HighEntropy, MeasureAs=KeyboardApiGetLayoutMap ] Promise<KeyboardLayoutMap> getLayoutMap(); };
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 163241d..d742c70 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
@@ -2307,6 +2307,7 @@ if (volume_slider_->IsFocused() || mute_button_->IsFocused()) { // When we're focusing with the keyboard, we don't need the delay. volume_slider_->OpenSlider(); + ShowVolumeControlHoverBackground(); } else { volume_slider_wanted_timer_.StartOneShot( WebTestSupport::IsRunningWebTest() ? kTimeToShowVolumeSliderTest
diff --git a/third_party/blink/renderer/modules/mediacapturefromelement/html_canvas_element_capture.idl b/third_party/blink/renderer/modules/mediacapturefromelement/html_canvas_element_capture.idl index 73eb3bb..4fe2c11 100644 --- a/third_party/blink/renderer/modules/mediacapturefromelement/html_canvas_element_capture.idl +++ b/third_party/blink/renderer/modules/mediacapturefromelement/html_canvas_element_capture.idl
@@ -6,5 +6,5 @@ [ ImplementedAs=HTMLCanvasElementCapture ] partial interface HTMLCanvasElement { - [RaisesException, CallWith=ScriptState] MediaStream captureStream (optional double frameRate); + [HighEntropy, MeasureAs=CanvasCaptureStream, RaisesException, CallWith=ScriptState] MediaStream captureStream (optional double frameRate); };
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices.idl b/third_party/blink/renderer/modules/mediastream/media_devices.idl index 8e803c5..71fbfd51 100644 --- a/third_party/blink/renderer/modules/mediastream/media_devices.idl +++ b/third_party/blink/renderer/modules/mediastream/media_devices.idl
@@ -11,7 +11,7 @@ ] interface MediaDevices : EventTarget { [RuntimeEnabled=OnDeviceChange] attribute EventHandler ondevicechange; [ - CallWith = ScriptState, MeasureAs = MediaDevicesEnumerateDevices + CallWith = ScriptState, HighEntropy, MeasureAs = MediaDevicesEnumerateDevices ] Promise<sequence<MediaDeviceInfo>> enumerateDevices(); MediaTrackSupportedConstraints getSupportedConstraints();
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni index 171bd9b..6ac635e 100644 --- a/third_party/blink/renderer/modules/modules_idl_files.gni +++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -76,12 +76,16 @@ "badging/badge.idl", "battery/battery_manager.idl", "bluetooth/bluetooth.idl", + "bluetooth/bluetooth_advertising_event.idl", "bluetooth/bluetooth_characteristic_properties.idl", "bluetooth/bluetooth_device.idl", + "bluetooth/bluetooth_le_scan.idl", + "bluetooth/bluetooth_manufacturer_data_map.idl", "bluetooth/bluetooth_remote_gatt_characteristic.idl", "bluetooth/bluetooth_remote_gatt_descriptor.idl", "bluetooth/bluetooth_remote_gatt_server.idl", "bluetooth/bluetooth_remote_gatt_service.idl", + "bluetooth/bluetooth_service_data_map.idl", "bluetooth/bluetooth_uuid.idl", "broadcastchannel/broadcast_channel.idl", "cache_storage/cache.idl", @@ -489,7 +493,9 @@ "background_fetch/background_fetch_options.idl", "background_fetch/background_fetch_ui_options.idl", "background_sync/sync_event_init.idl", + "bluetooth/bluetooth_advertising_event_init.idl", "bluetooth/bluetooth_le_scan_filter_init.idl", + "bluetooth/bluetooth_le_scan_options.idl", "bluetooth/request_device_options.idl", "cache_storage/cache_query_options.idl", "canvas/canvas2d/canvas_rendering_context_2d_settings.idl",
diff --git a/third_party/blink/renderer/modules/payments/payment_request.idl b/third_party/blink/renderer/modules/payments/payment_request.idl index f7837401..2cfcb5e 100644 --- a/third_party/blink/renderer/modules/payments/payment_request.idl +++ b/third_party/blink/renderer/modules/payments/payment_request.idl
@@ -16,7 +16,7 @@ ] interface PaymentRequest : EventTarget { [CallWith=ScriptState, NewObject] Promise<PaymentResponse> show(); [CallWith=ScriptState, NewObject] Promise<void> abort(); - [CallWith=ScriptState, NewObject] Promise<boolean> canMakePayment(); + [CallWith=ScriptState, HighEntropy, Measure, NewObject] Promise<boolean> canMakePayment(); readonly attribute DOMString id; [ImplementedAs=getShippingAddress] readonly attribute PaymentAddress? shippingAddress;
diff --git a/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc b/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc index 9bb7822..977331d 100644 --- a/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc +++ b/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc
@@ -53,7 +53,7 @@ void OnReadPacket(rtc::PacketTransportInternal* packet_transport, const char* buffer, size_t buffer_length, - const rtc::PacketTime& packet_time, + const int64_t& packet_time, int flags) { DCHECK_EQ(packet_transport, p2p_transport_channel_); if (!receive_delegate_) {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc index 607822a..40994c8 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -1952,17 +1952,14 @@ // Custom binding for spec-compliant "getStats(MediaStreamTrack? selector)". // null is a valid selector value, but value of wrong type isn't. |selector| // set to no value means type error. - base::Optional<MediaStreamTrack*> selector; - if (argument->IsNull()) { - selector = base::Optional<MediaStreamTrack*>(nullptr); - } else { - MediaStreamTrack* track = - V8MediaStreamTrack::ToImplWithTypeCheck(isolate, argument); - if (track) - selector = base::Optional<MediaStreamTrack*>(track); - } - if (selector.has_value()) - return PromiseBasedGetStats(script_state, *selector); + if (argument->IsNull()) + return PromiseBasedGetStats(script_state, nullptr); + + MediaStreamTrack* track = + V8MediaStreamTrack::ToImplWithTypeCheck(isolate, argument); + if (track) + return PromiseBasedGetStats(script_state, track); + ExceptionState exception_state(isolate, ExceptionState::kExecutionContext, "RTCPeerConnection", "getStats"); exception_state.ThrowTypeError(
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc index 3c870f8..b2b9a85 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -499,4 +499,14 @@ return std::move(cache_storage_info_); } +int ServiceWorkerGlobalScope::WillStartTask() { + return ServiceWorkerGlobalScopeClient::From(GetExecutionContext()) + ->WillStartTask(); +} + +void ServiceWorkerGlobalScope::DidEndTask(int task_id) { + ServiceWorkerGlobalScopeClient::From(GetExecutionContext()) + ->DidEndTask(task_id); +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h index 49089a5..62f6cac4 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
@@ -140,6 +140,10 @@ mojom::blink::CacheStoragePtrInfo TakeCacheStorage(); + // See the functions of the same name in WebServiceWorkerContextClient. + int WillStartTask(); + void DidEndTask(int task_id); + DEFINE_ATTRIBUTE_EVENT_LISTENER(install, kInstall); DEFINE_ATTRIBUTE_EVENT_LISTENER(activate, kActivate); DEFINE_ATTRIBUTE_EVENT_LISTENER(fetch, kFetch);
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.cc index a90f554..99444af33 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.cc
@@ -300,6 +300,14 @@ service_worker_host_.reset(); } +int ServiceWorkerGlobalScopeClient::WillStartTask() { + return client_.WillStartTask(); +} + +void ServiceWorkerGlobalScopeClient::DidEndTask(int task_id) { + client_.DidEndTask(task_id); +} + const char ServiceWorkerGlobalScopeClient::kSupplementName[] = "ServiceWorkerGlobalScopeClient";
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h index 1959da5..c6c8f0c 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h
@@ -139,6 +139,9 @@ void WillDestroyWorkerContext(); + int WillStartTask(); + void DidEndTask(int task_id); + static ServiceWorkerGlobalScopeClient* From(ExecutionContext*); void Trace(blink::Visitor*) override;
diff --git a/third_party/blink/renderer/modules/webaudio/analyser_node.idl b/third_party/blink/renderer/modules/webaudio/analyser_node.idl index 7593662..d6578a7 100644 --- a/third_party/blink/renderer/modules/webaudio/analyser_node.idl +++ b/third_party/blink/renderer/modules/webaudio/analyser_node.idl
@@ -42,10 +42,10 @@ // Copies the current frequency data into the passed array. // If the array has fewer elements than the frequencyBinCount, the excess elements will be dropped. - void getFloatFrequencyData(Float32Array array); - void getByteFrequencyData(Uint8Array array); + [HighEntropy, Measure] void getFloatFrequencyData(Float32Array array); + [HighEntropy, Measure] void getByteFrequencyData(Uint8Array array); // Real-time waveform data - void getFloatTimeDomainData(Float32Array array); - void getByteTimeDomainData(Uint8Array array); + [HighEntropy, Measure] void getFloatTimeDomainData(Float32Array array); + [HighEntropy, Measure] void getByteTimeDomainData(Uint8Array array); };
diff --git a/third_party/blink/renderer/modules/webaudio/audio_buffer.idl b/third_party/blink/renderer/modules/webaudio/audio_buffer.idl index 08e683e..650c785f 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_buffer.idl +++ b/third_party/blink/renderer/modules/webaudio/audio_buffer.idl
@@ -38,7 +38,7 @@ // Channel access readonly attribute unsigned long numberOfChannels; - [RaisesException] Float32Array getChannelData(unsigned long channelIndex); - [RaisesException] void copyFromChannel(Float32Array destination, long channelNumber, optional unsigned long startInChannel = 0); + [HighEntropy, Measure, RaisesException] Float32Array getChannelData(unsigned long channelIndex); + [HighEntropy, Measure, RaisesException] void copyFromChannel(Float32Array destination, long channelNumber, optional unsigned long startInChannel = 0); [RaisesException] void copyToChannel(Float32Array source, long channelNumber, optional unsigned long startInChannel = 0); };
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc index b584dc34..f4bb7bf 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -37,6 +37,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/html_canvas_element_or_offscreen_canvas.h" #include "third_party/blink/renderer/bindings/modules/v8/webgl_any.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/core/frame/dactyloscoper.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h" #include "third_party/blink/renderer/core/frame/settings.h" @@ -2965,6 +2966,12 @@ const String& name) { WebGLExtension* extension = nullptr; + if (name == WebGLDebugRendererInfo::ExtensionName()) { + ExecutionContext* context = ExecutionContext::From(script_state); + UseCounter::Count(context, WebFeature::kWebGLDebugRendererInfo); + Dactyloscoper::Record(context, WebFeature::kWebGLDebugRendererInfo); + } + if (!isContextLost()) { for (ExtensionTracker* tracker : extensions_) { if (tracker->MatchesNameWithPrefixes(name)) {
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.idl b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.idl index 5857522..46b48b4 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.idl +++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.idl
@@ -553,7 +553,7 @@ GLenum getError(); - [CallWith=ScriptState] object? getExtension(DOMString name); + [CallWith=ScriptState, HighEntropy, Measure] object? getExtension(DOMString name); [CallWith=ScriptState] any getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname); [CallWith=ScriptState] any getParameter(GLenum pname); @@ -568,7 +568,7 @@ DOMString? getShaderSource(WebGLShader shader); - sequence<DOMString>? getSupportedExtensions(); + [HighEntropy, Measure] sequence<DOMString>? getSupportedExtensions(); [CallWith=ScriptState] any getTexParameter(GLenum target, GLenum pname);
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index 54fdfea..a14d15f0 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1091,6 +1091,7 @@ "graphics/picture_snapshot.h", "graphics/placeholder_image.cc", "graphics/placeholder_image.h", + "graphics/platform_paint_worklet_input.h", "graphics/profiling_canvas.cc", "graphics/profiling_canvas.h", "graphics/replaying_canvas.cc",
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc index b9c4fe0..6797fb98 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -55,6 +55,10 @@ RuntimeEnabledFeatures::SetWebBluetoothEnabled(enable); } +void WebRuntimeFeatures::EnableWebBluetoothScanning(bool enable) { + RuntimeEnabledFeatures::SetWebBluetoothScanningEnabled(enable); +} + void WebRuntimeFeatures::EnableWebNfc(bool enable) { RuntimeEnabledFeatures::SetWebNFCEnabled(enable); }
diff --git a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc index 6cd1c36..3214da58 100644 --- a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc +++ b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
@@ -4,7 +4,6 @@ #include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h" -#include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/common/sync_token.h" #include "third_party/blink/public/platform/platform.h" @@ -40,19 +39,17 @@ unsigned texture_id, base::WeakPtr<WebGraphicsContext3DProviderWrapper>&& context_provider_wrapper, - IntSize mailbox_size, - MailboxType mailbox_type) { + IntSize mailbox_size) { return base::AdoptRef(new AcceleratedStaticBitmapImage( mailbox, sync_token, texture_id, std::move(context_provider_wrapper), - mailbox_size, mailbox_type)); + mailbox_size)); } AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage( sk_sp<SkImage> image, base::WeakPtr<WebGraphicsContext3DProviderWrapper>&& context_provider_wrapper) - : paint_image_content_id_(cc::PaintImage::GetNextContentId()), - mailbox_type_(MailboxType::kDeprecatedMailbox) { + : paint_image_content_id_(cc::PaintImage::GetNextContentId()) { CHECK(image && image->isTextureBacked()); texture_holder_ = std::make_unique<SkiaTextureHolder>( std::move(image), std::move(context_provider_wrapper)); @@ -64,10 +61,8 @@ unsigned texture_id, base::WeakPtr<WebGraphicsContext3DProviderWrapper>&& context_provider_wrapper, - IntSize mailbox_size, - MailboxType mailbox_type) - : paint_image_content_id_(cc::PaintImage::GetNextContentId()), - mailbox_type_(mailbox_type) { + IntSize mailbox_size) + : paint_image_content_id_(cc::PaintImage::GetNextContentId()) { texture_holder_ = std::make_unique<MailboxTextureHolder>( mailbox, sync_token, texture_id, std::move(context_provider_wrapper), mailbox_size); @@ -171,25 +166,14 @@ // Get a texture id that |destProvider| knows about and copy from it. dest_gl->WaitSyncTokenCHROMIUM( texture_holder_->GetSyncToken().GetConstData()); - GLuint source_texture_id; - if (mailbox_type_ == MailboxType::kSharedImageId) { - source_texture_id = dest_gl->CreateAndTexStorage2DSharedImageCHROMIUM( - texture_holder_->GetMailbox().name); - dest_gl->BeginSharedImageAccessDirectCHROMIUM( - source_texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM); - } else { - source_texture_id = dest_gl->CreateAndConsumeTextureCHROMIUM( - texture_holder_->GetMailbox().name); - } + GLuint source_texture_id = dest_gl->CreateAndConsumeTextureCHROMIUM( + texture_holder_->GetMailbox().name); dest_gl->CopySubTextureCHROMIUM( source_texture_id, 0, dest_target, dest_texture_id, 0, dest_point.X(), dest_point.Y(), source_sub_rectangle.X(), source_sub_rectangle.Y(), source_sub_rectangle.Width(), source_sub_rectangle.Height(), unpack_flip_y ? GL_FALSE : GL_TRUE, GL_FALSE, unpack_premultiply_alpha ? GL_FALSE : GL_TRUE); - if (mailbox_type_ == MailboxType::kSharedImageId) { - dest_gl->EndSharedImageAccessDirectCHROMIUM(source_texture_id); - } // This drops the |destGL| context's reference on our |m_mailbox|, but it's // still held alive by our SkImage. dest_gl->DeleteTextures(1, &source_texture_id);
diff --git a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h index 0a7e236c..fa769532 100644 --- a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h +++ b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h
@@ -23,27 +23,21 @@ class PLATFORM_EXPORT AcceleratedStaticBitmapImage final : public StaticBitmapImage { public: - enum class MailboxType { kSharedImageId, kDeprecatedMailbox }; - ~AcceleratedStaticBitmapImage() override; // SkImage with a texture backing. static scoped_refptr<AcceleratedStaticBitmapImage> CreateFromSkImage( sk_sp<SkImage>, base::WeakPtr<WebGraphicsContext3DProviderWrapper>); - // Can specify the GrContext that created the texture backing. Ideally all // callers would use this option. The |mailbox| is a name for the texture - // backing, allowing other contexts to use the same backing. |mailbox_type| - // indicates whether |mailbox| is a SharedImage indentifier or a deprecated - // mailbox (generated via ProduceTextureDirectCHROMIUM). + // backing, allowing other contexts to use the same backing. static scoped_refptr<AcceleratedStaticBitmapImage> CreateFromWebGLContextImage( const gpu::Mailbox&, const gpu::SyncToken&, unsigned texture_id, base::WeakPtr<WebGraphicsContext3DProviderWrapper>&&, - IntSize mailbox_size, - MailboxType mailbox_type = MailboxType::kDeprecatedMailbox); + IntSize mailbox_size); bool CurrentFrameKnownToBeOpaque() override; IntSize Size() const override; @@ -107,8 +101,7 @@ const gpu::SyncToken&, unsigned texture_id, base::WeakPtr<WebGraphicsContext3DProviderWrapper>&&, - IntSize mailbox_size, - MailboxType mailbox_type); + IntSize mailbox_size); void CreateImageFromMailboxIfNeeded(); void WaitSyncTokenIfNeeded(); @@ -124,8 +117,6 @@ scoped_refptr<base::SingleThreadTaskRunner> original_skia_image_task_runner_; base::WeakPtr<WebGraphicsContext3DProviderWrapper> original_skia_image_context_provider_wrapper_; - - const MailboxType mailbox_type_; }; } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/gpu/DEPS b/third_party/blink/renderer/platform/graphics/gpu/DEPS index 5effcc4e..adce483a 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/DEPS +++ b/third_party/blink/renderer/platform/graphics/gpu/DEPS
@@ -1,15 +1,12 @@ include_rules = [ - "+components/viz/test/test_context_provider.h", "+mojo/public/cpp/bindings/binding.h", "+mojo/public/cpp/system/platform_handle.h", "+device/vr/public/mojom/vr_service.mojom-blink.h", "+gpu/command_buffer/client/gles2_interface.h", "+gpu/command_buffer/client/gles2_interface_stub.h", - "+gpu/command_buffer/client/shared_image_interface.h", "+gpu/command_buffer/common/capabilities.h", "+gpu/command_buffer/common/gpu_memory_buffer_support.h", "+gpu/command_buffer/common/mailbox_holder.h", - "+gpu/command_buffer/common/shared_image_usage.h", "+gpu/config/gpu_driver_bug_workaround_type.h", "+gpu/config/gpu_feature_info.h", "+ui/gfx/gpu_fence.h",
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc index f0a7225..06fd08f6 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
@@ -43,10 +43,8 @@ #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" -#include "gpu/command_buffer/client/shared_image_interface.h" #include "gpu/command_buffer/common/capabilities.h" #include "gpu/command_buffer/common/gpu_memory_buffer_support.h" -#include "gpu/command_buffer/common/shared_image_usage.h" #include "gpu/config/gpu_driver_bug_workaround_type.h" #include "gpu/config/gpu_feature_info.h" #include "third_party/blink/public/platform/platform.h" @@ -440,10 +438,6 @@ size_.Height(), GL_FALSE, GL_FALSE, GL_FALSE); } - // Signal we will no longer access |color_buffer_for_mailbox| before exporting - // it. - gl_->EndSharedImageAccessDirectCHROMIUM(color_buffer_for_mailbox->texture_id); - // Put colorBufferForMailbox into its mailbox, and populate its // produceSyncToken with that point. { @@ -466,7 +460,7 @@ // Populate the output mailbox and callback. { - bool is_overlay_candidate = !!color_buffer_for_mailbox->gpu_memory_buffer; + bool is_overlay_candidate = color_buffer_for_mailbox->image_id != 0; *out_resource = viz::TransferableResource::MakeGLOverlay( color_buffer_for_mailbox->mailbox, GL_LINEAR, texture_target_, color_buffer_for_mailbox->produce_sync_token, gfx::Size(size_), @@ -573,7 +567,7 @@ // TODO(danakj): Instead of using PrepareTransferableResourceInternal(), we // could just use the actual texture id and avoid needing to produce/consume a // mailbox. - GLuint texture_id = gl_->CreateAndTexStorage2DSharedImageCHROMIUM( + GLuint texture_id = gl_->CreateAndConsumeTextureCHROMIUM( transferable_resource.mailbox_holder.mailbox.name); if (out_release_callback) { @@ -603,8 +597,7 @@ // in DrawingBuffer. return AcceleratedStaticBitmapImage::CreateFromWebGLContextImage( sk_image_mailbox, sk_image_sync_token, texture_id, - context_provider_->GetWeakPtr(), size_, - AcceleratedStaticBitmapImage::MailboxType::kSharedImageId); + context_provider_->GetWeakPtr(), size_); } scoped_refptr<DrawingBuffer::ColorBuffer> DrawingBuffer::CreateOrRecycleColorBuffer() { @@ -615,8 +608,6 @@ if (recycled->receive_sync_token.HasData()) gl_->WaitSyncTokenCHROMIUM(recycled->receive_sync_token.GetData()); DCHECK(recycled->size == size_); - gl_->BeginSharedImageAccessDirectCHROMIUM( - recycled->texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM); return recycled; } return CreateColorBuffer(size_); @@ -641,24 +632,49 @@ DrawingBuffer* drawing_buffer, const IntSize& size, GLuint texture_id, - std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer, - gpu::Mailbox mailbox) + GLuint image_id, + std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer) : drawing_buffer(drawing_buffer), size(size), texture_id(texture_id), - gpu_memory_buffer(std::move(gpu_memory_buffer)), - mailbox(mailbox) {} + image_id(image_id), + gpu_memory_buffer(std::move(gpu_memory_buffer)) { + gpu::gles2::GLES2Interface* gl = drawing_buffer->ContextGL(); + gl->ProduceTextureDirectCHROMIUM(texture_id, mailbox.name); +} DrawingBuffer::ColorBuffer::~ColorBuffer() { gpu::gles2::GLES2Interface* gl = drawing_buffer->gl_; - gpu::SharedImageInterface* sii = - drawing_buffer->ContextProvider()->SharedImageInterface(); - - sii->DestroySharedImage(receive_sync_token, mailbox); - gpu_memory_buffer.reset(); + GLenum texture_target = drawing_buffer->texture_target_; + if (receive_sync_token.HasData()) + gl->WaitSyncTokenCHROMIUM(receive_sync_token.GetConstData()); + if (image_id) { + gl->BindTexture(texture_target, texture_id); + gl->ReleaseTexImage2DCHROMIUM(texture_target, image_id); + if (rgb_workaround_texture_id) { + gl->BindTexture(texture_target, rgb_workaround_texture_id); + gl->ReleaseTexImage2DCHROMIUM(texture_target, image_id); + } + gl->DestroyImageCHROMIUM(image_id); + switch (texture_target) { + case GL_TEXTURE_2D: + // Restore the texture binding for GL_TEXTURE_2D, since the client will + // expect the previous state. + if (drawing_buffer->client_) + drawing_buffer->client_->DrawingBufferClientRestoreTexture2DBinding(); + break; + case GC3D_TEXTURE_RECTANGLE_ARB: + // Rectangle textures aren't exposed to WebGL, so don't bother + // restoring this state (there is no meaningful way to restore it). + break; + default: + NOTREACHED(); + break; + } + gpu_memory_buffer.reset(); + } gl->DeleteTextures(1, &texture_id); if (rgb_workaround_texture_id) { - sii->DestroySharedImage(receive_sync_token, rgb_workaround_mailbox); // Avoid deleting this texture if it was unused. gl->DeleteTextures(1, &rgb_workaround_texture_id); } @@ -850,23 +866,25 @@ // through a mailbox first. gpu::Mailbox mailbox; gpu::SyncToken produce_sync_token; - GLuint texture_id_to_restore_access = 0; if (src_buffer == kFrontBuffer && front_color_buffer_) { mailbox = front_color_buffer_->mailbox; produce_sync_token = front_color_buffer_->produce_sync_token; } else { - GLuint texture_id = 0; if (premultiplied_alpha_false_texture_) { - DCHECK(!premultiplied_alpha_false_mailbox_.IsZero()); + // If this texture exists, then it holds the rendering results at this + // point, rather than back_color_buffer_. back_color_buffer_ receives the + // contents of this texture later, premultiplying alpha into the color + // channels. We lazily produce a mailbox for it. + if (premultiplied_alpha_false_mailbox_.IsZero()) { + src_gl->ProduceTextureDirectCHROMIUM( + premultiplied_alpha_false_texture_, + premultiplied_alpha_false_mailbox_.name); + } mailbox = premultiplied_alpha_false_mailbox_; - texture_id = premultiplied_alpha_false_texture_; } else { mailbox = back_color_buffer_->mailbox; - texture_id = back_color_buffer_->texture_id; } - src_gl->EndSharedImageAccessDirectCHROMIUM(texture_id); src_gl->GenUnverifiedSyncTokenCHROMIUM(produce_sync_token.GetData()); - texture_id_to_restore_access = texture_id; } if (!produce_sync_token.HasData()) { @@ -875,9 +893,7 @@ } dst_gl->WaitSyncTokenCHROMIUM(produce_sync_token.GetConstData()); - - GLuint src_texture = - dst_gl->CreateAndTexStorage2DSharedImageCHROMIUM(mailbox.name); + GLuint src_texture = dst_gl->CreateAndConsumeTextureCHROMIUM(mailbox.name); GLboolean unpack_premultiply_alpha_needed = GL_FALSE; GLboolean unpack_unpremultiply_alpha_needed = GL_FALSE; @@ -886,25 +902,19 @@ else if (want_alpha_channel_ && !premultiplied_alpha_ && premultiply_alpha) unpack_premultiply_alpha_needed = GL_TRUE; - dst_gl->BeginSharedImageAccessDirectCHROMIUM( - src_texture, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM); dst_gl->CopySubTextureCHROMIUM( src_texture, 0, dst_texture_target, dst_texture, 0, dst_texture_offset.X(), dst_texture_offset.Y(), src_sub_rectangle.X(), src_sub_rectangle.Y(), src_sub_rectangle.Width(), src_sub_rectangle.Height(), flip_y, unpack_premultiply_alpha_needed, unpack_unpremultiply_alpha_needed); - dst_gl->EndSharedImageAccessDirectCHROMIUM(src_texture); + dst_gl->DeleteTextures(1, &src_texture); gpu::SyncToken sync_token; dst_gl->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData()); src_gl->WaitSyncTokenCHROMIUM(sync_token.GetData()); - if (texture_id_to_restore_access) { - src_gl->BeginSharedImageAccessDirectCHROMIUM( - texture_id_to_restore_access, - GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM); - } + return true; } @@ -967,12 +977,7 @@ gl_->DeleteRenderbuffers(1, &depth_stencil_buffer_); if (premultiplied_alpha_false_texture_) { - gl_->EndSharedImageAccessDirectCHROMIUM(premultiplied_alpha_false_texture_); gl_->DeleteTextures(1, &premultiplied_alpha_false_texture_); - gpu::SharedImageInterface* sii = ContextProvider()->SharedImageInterface(); - gpu::SyncToken sync_token; - gl_->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData()); - sii->DestroySharedImage(sync_token, premultiplied_alpha_false_mailbox_); premultiplied_alpha_false_mailbox_.SetZero(); } @@ -1004,36 +1009,42 @@ // via CopySubTextureCHROMIUM, performing the premultiplication step then. if (ShouldUseChromiumImage() && allocate_alpha_channel_ && !premultiplied_alpha_) { - gpu::SharedImageInterface* sii = ContextProvider()->SharedImageInterface(); state_restorer_->SetTextureBindingDirty(); // TODO(kbr): unify with code in CreateColorBuffer. if (premultiplied_alpha_false_texture_) { - gl_->EndSharedImageAccessDirectCHROMIUM( - premultiplied_alpha_false_texture_); gl_->DeleteTextures(1, &premultiplied_alpha_false_texture_); - gpu::SyncToken sync_token; - gl_->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData()); - sii->DestroySharedImage(sync_token, premultiplied_alpha_false_mailbox_); premultiplied_alpha_false_mailbox_.SetZero(); premultiplied_alpha_false_texture_ = 0; } - viz::ResourceFormat format; - if (use_half_float_storage_) - format = viz::RGBA_F16; - else - format = viz::RGBA_8888; - premultiplied_alpha_false_mailbox_ = sii->CreateSharedImage( - format, static_cast<gfx::Size>(size), storage_color_space_, - gpu::SHARED_IMAGE_USAGE_GLES2 | - gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT); - gpu::SyncToken sync_token = sii->GenUnverifiedSyncToken(); - gl_->WaitSyncTokenCHROMIUM(sync_token.GetConstData()); - premultiplied_alpha_false_texture_ = - gl_->CreateAndTexStorage2DSharedImageCHROMIUM( - premultiplied_alpha_false_mailbox_.name); - gl_->BeginSharedImageAccessDirectCHROMIUM( - premultiplied_alpha_false_texture_, - GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM); + gl_->GenTextures(1, &premultiplied_alpha_false_texture_); + // The command decoder forbids allocating "real" OpenGL textures with the + // GL_TEXTURE_RECTANGLE_ARB target. Allocate this temporary texture with + // type GL_TEXTURE_2D all the time. CopySubTextureCHROMIUM can handle + // copying between 2D and rectangular textures. + gl_->BindTexture(GL_TEXTURE_2D, premultiplied_alpha_false_texture_); + if (storage_texture_supported_) { + GLenum internal_storage_format = GL_RGBA8; + if (use_half_float_storage_) { + internal_storage_format = GL_RGBA16F_EXT; + } + gl_->TexStorage2DEXT(GL_TEXTURE_2D, 1, internal_storage_format, + size.Width(), size.Height()); + } else { + GLenum internal_format = GL_RGBA; + GLenum format = internal_format; + GLenum data_type = GL_UNSIGNED_BYTE; + if (use_half_float_storage_) { + if (webgl_version_ > kWebGL1) { + internal_format = GL_RGBA16F; + data_type = GL_HALF_FLOAT; + } else { + internal_format = GL_RGBA; + data_type = GL_HALF_FLOAT_OES; + } + } + gl_->TexImage2D(GL_TEXTURE_2D, 0, internal_format, size.Width(), + size.Height(), 0, format, data_type, nullptr); + } } AttachColorBufferToReadFramebuffer(); @@ -1402,14 +1413,12 @@ state_restorer_->SetFramebufferBindingDirty(); state_restorer_->SetTextureBindingDirty(); - gpu::SharedImageInterface* sii = ContextProvider()->SharedImageInterface(); + // Select the parameters for the texture object. Allocate the backing + // GpuMemoryBuffer and GLImage, if one is going to be used. + GLuint image_id = 0; + std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer; gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager = Platform::Current()->GetGpuMemoryBufferManager(); - - gpu::Mailbox mailbox; - GLuint texture_id = 0; - std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer; - if (ShouldUseChromiumImage()) { gfx::BufferFormat buffer_format; if (allocate_alpha_channel_) { @@ -1424,57 +1433,67 @@ buffer_format = gfx::BufferFormat::BGRX_8888; } } - // TODO(crbug.com/911176): When RGB emulation is not needed, we should use - // the non-GMB CreateSharedImage with gpu::SHARED_IMAGE_USAGE_SCANOUT in - // order to allocate the GMB service-side and avoid a synchronous round-trip - // to the browser process here. gpu_memory_buffer = gpu_memory_buffer_manager->CreateGpuMemoryBuffer( gfx::Size(size), buffer_format, gfx::BufferUsage::SCANOUT, gpu::kNullSurfaceHandle); - if (gpu_memory_buffer) { - mailbox = sii->CreateSharedImage( - gpu_memory_buffer.get(), gpu_memory_buffer_manager, - storage_color_space_, - gpu::SHARED_IMAGE_USAGE_GLES2 | - gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT | - gpu::SHARED_IMAGE_USAGE_DISPLAY | - gpu::SHARED_IMAGE_USAGE_SCANOUT); + gpu_memory_buffer->SetColorSpace(storage_color_space_); + const GLenum gl_format = allocate_alpha_channel_ ? GL_RGBA : GL_RGB; + + image_id = + gl_->CreateImageCHROMIUM(gpu_memory_buffer->AsClientBuffer(), + size.Width(), size.Height(), gl_format); + if (!image_id) + gpu_memory_buffer.reset(); } } - // Create a normal SharedImage if GpuMemoryBuffer is not needed or the - // allocation above failed. - if (!gpu_memory_buffer) { - viz::ResourceFormat format; - if (allocate_alpha_channel_) { - if (use_half_float_storage_) - format = viz::RGBA_F16; - else - format = viz::RGBA_8888; + // Allocate the texture for this object. + GLuint texture_id = 0; + { + gl_->GenTextures(1, &texture_id); + gl_->BindTexture(texture_target_, texture_id); + gl_->TexParameteri(texture_target_, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gl_->TexParameteri(texture_target_, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl_->TexParameteri(texture_target_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl_->TexParameteri(texture_target_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + + // If this is GpuMemoryBuffer-backed, then bind the texture to the + // GpuMemoryBuffer's GLImage. Otherwise, allocate ordinary texture storage. + if (image_id) { + gl_->BindTexImage2DCHROMIUM(texture_target_, image_id); + } else { + if (storage_texture_supported_) { + GLenum internal_storage_format = + allocate_alpha_channel_ ? GL_RGBA8 : GL_RGB8; + if (use_half_float_storage_) { + DCHECK(want_alpha_channel_); + internal_storage_format = GL_RGBA16F_EXT; + } + gl_->TexStorage2DEXT(GL_TEXTURE_2D, 1, internal_storage_format, + size.Width(), size.Height()); } else { - DCHECK(!use_half_float_storage_); - format = viz::RGBX_8888; + GLenum internal_format = allocate_alpha_channel_ ? GL_RGBA : GL_RGB; + GLenum format = internal_format; + GLenum data_type = GL_UNSIGNED_BYTE; + if (use_half_float_storage_) { + DCHECK(want_alpha_channel_); + if (webgl_version_ > kWebGL1) { + internal_format = GL_RGBA16F; + data_type = GL_HALF_FLOAT; + } else { + internal_format = GL_RGBA; + data_type = GL_HALF_FLOAT_OES; + } + } + gl_->TexImage2D(texture_target_, 0, internal_format, size.Width(), + size.Height(), 0, format, data_type, nullptr); } - - mailbox = sii->CreateSharedImage( - format, static_cast<gfx::Size>(size), storage_color_space_, - gpu::SHARED_IMAGE_USAGE_GLES2 | - gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT | - gpu::SHARED_IMAGE_USAGE_DISPLAY); } - // Import the allocated SharedImage into GL. - gpu::SyncToken sync_token = sii->GenUnverifiedSyncToken(); - gl_->WaitSyncTokenCHROMIUM(sync_token.GetConstData()); - texture_id = gl_->CreateAndTexStorage2DSharedImageCHROMIUM(mailbox.name); - gl_->BindTexture(texture_target_, texture_id); - gl_->BeginSharedImageAccessDirectCHROMIUM( - texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM); - - // Clear the alpha channel if we allocated a GpuMemoryBuffer and RGB emulation - // is required. - if (gpu_memory_buffer && !want_alpha_channel_ && have_alpha_channel_) { + // Clear the alpha channel if this is RGB emulated. + if (image_id && !want_alpha_channel_ && have_alpha_channel_) { GLuint fbo = 0; state_restorer_->SetClearStateDirty(); @@ -1491,8 +1510,8 @@ gl_->DeleteFramebuffers(1, &fbo); } - return base::AdoptRef(new ColorBuffer(this, size, texture_id, - std::move(gpu_memory_buffer), mailbox)); + return base::AdoptRef(new ColorBuffer(this, size, texture_id, image_id, + std::move(gpu_memory_buffer))); } void DrawingBuffer::AttachColorBufferToReadFramebuffer() { @@ -1554,7 +1573,7 @@ // If for some reason the back buffer doesn't exist or doesn't have a // CHROMIUM_image, don't proceed with this workaround. - if (!back_color_buffer_ || !back_color_buffer_->gpu_memory_buffer) + if (!back_color_buffer_ || !back_color_buffer_->image_id) return false; // Before allowing the BlitFramebuffer call to go through, it's necessary @@ -1570,24 +1589,21 @@ GLuint rgb_texture = back_color_buffer_->rgb_workaround_texture_id; DCHECK_EQ(texture_target_, GC3D_TEXTURE_RECTANGLE_ARB); if (!rgb_texture) { - gpu::SharedImageInterface* sii = ContextProvider()->SharedImageInterface(); - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager = - Platform::Current()->GetGpuMemoryBufferManager(); - back_color_buffer_->rgb_workaround_mailbox = sii->CreateSharedImage( - back_color_buffer_->gpu_memory_buffer.get(), gpu_memory_buffer_manager, - storage_color_space_, - gpu::SHARED_IMAGE_USAGE_GLES2 | - gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT | - gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT | - gpu::SHARED_IMAGE_USAGE_RGB_EMULATION); - gl_->WaitSyncTokenCHROMIUM(sii->GenUnverifiedSyncToken().GetConstData()); - rgb_texture = gl_->CreateAndTexStorage2DSharedImageCHROMIUM( - back_color_buffer_->rgb_workaround_mailbox.name); + gl_->GenTextures(1, &rgb_texture); + gl_->BindTexture(texture_target_, rgb_texture); + gl_->TexParameteri(texture_target_, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gl_->TexParameteri(texture_target_, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl_->TexParameteri(texture_target_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl_->TexParameteri(texture_target_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + // Bind this texture to the CHROMIUM_image instance that the color + // buffer owns. This is an expensive operation, so it's important that + // the result be cached. + gl_->BindTexImage2DWithInternalformatCHROMIUM(texture_target_, GL_RGB, + back_color_buffer_->image_id); back_color_buffer_->rgb_workaround_texture_id = rgb_texture; } - gl_->BeginSharedImageAccessDirectCHROMIUM( - rgb_texture, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM); gl_->FramebufferTexture2D(GL_DRAW_FRAMEBUFFER_ANGLE, GL_COLOR_ATTACHMENT0, texture_target_, rgb_texture, 0); return true; @@ -1597,9 +1613,7 @@ // This will only be called if SetupRGBEmulationForBlitFramebuffer was. // Put the framebuffer back the way it was, and clear the alpha channel. DCHECK(back_color_buffer_); - DCHECK(back_color_buffer_->gpu_memory_buffer); - gl_->EndSharedImageAccessDirectCHROMIUM( - back_color_buffer_->rgb_workaround_texture_id); + DCHECK(back_color_buffer_->image_id); gl_->FramebufferTexture2D(GL_DRAW_FRAMEBUFFER_ANGLE, GL_COLOR_ATTACHMENT0, texture_target_, back_color_buffer_->texture_id, 0); // Clear the alpha channel.
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h index 616722f..82a8e39 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h +++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h
@@ -333,8 +333,8 @@ ColorBuffer(DrawingBuffer*, const IntSize&, GLuint texture_id, - std::unique_ptr<gfx::GpuMemoryBuffer>, - gpu::Mailbox mailbox); + GLuint image_id, + std::unique_ptr<gfx::GpuMemoryBuffer>); ~ColorBuffer(); // The owning DrawingBuffer. Note that DrawingBuffer is explicitly destroyed @@ -343,6 +343,7 @@ scoped_refptr<DrawingBuffer> drawing_buffer; const IntSize size; const GLuint texture_id = 0; + const GLuint image_id = 0; std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer; // If we're emulating an RGB back buffer using an RGBA Chromium @@ -355,9 +356,6 @@ // situation (the alpha channel is zeroed), requiring more fixups. GLuint rgb_workaround_texture_id = 0; - // The mailbox for |rgb_workaround_texture_id|. - gpu::Mailbox rgb_workaround_mailbox; - // The mailbox used to send this buffer to the compositor. gpu::Mailbox mailbox;
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc index 5e8e2f3..2fdde1208 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc
@@ -51,10 +51,6 @@ namespace blink { -MATCHER_P(SyncTokenEq, token, "") { - return *reinterpret_cast<const gpu::SyncToken*>(arg) == token; -} - class DrawingBufferTest : public Test { protected: void SetUp() override { Init(kDisableMultisampling); } @@ -145,9 +141,7 @@ } TEST_F(DrawingBufferTest, VerifyResizingProperlyAffectsResources) { - viz::TestSharedImageInterface* sii = - drawing_buffer_->SharedImageInterfaceForTests(); - + GLES2InterfaceForTests* gl_ = drawing_buffer_->ContextGLForTests(); VerifyStateWasRestored(); viz::TransferableResource resource; std::unique_ptr<viz::SingleReleaseCallback> release_callback; @@ -160,7 +154,7 @@ EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource, &release_callback)); VerifyStateWasRestored(); - EXPECT_EQ(static_cast<gfx::Size>(initial_size), sii->MostRecentSize()); + EXPECT_EQ(initial_size, gl_->MostRecentlyProducedSize()); // Resize to 100x50. drawing_buffer_->Resize(alternate_size); @@ -172,7 +166,7 @@ EXPECT_TRUE(drawing_buffer_->MarkContentsChanged()); EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource, &release_callback)); - EXPECT_EQ(static_cast<gfx::Size>(alternate_size), sii->MostRecentSize()); + EXPECT_EQ(alternate_size, gl_->MostRecentlyProducedSize()); VerifyStateWasRestored(); // Reset to initial size. @@ -186,7 +180,7 @@ EXPECT_TRUE(drawing_buffer_->MarkContentsChanged()); EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource, &release_callback)); - EXPECT_EQ(static_cast<gfx::Size>(initial_size), sii->MostRecentSize()); + EXPECT_EQ(initial_size, gl_->MostRecentlyProducedSize()); VerifyStateWasRestored(); // Prepare one final resource and verify that it's the correct size. @@ -195,7 +189,7 @@ EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource, &release_callback)); VerifyStateWasRestored(); - EXPECT_EQ(static_cast<gfx::Size>(initial_size), sii->MostRecentSize()); + EXPECT_EQ(initial_size, gl_->MostRecentlyProducedSize()); release_callback->Run(gpu::SyncToken(), false /* lostResource */); drawing_buffer_->BeginDestruction(); } @@ -353,36 +347,31 @@ // Produce resources. EXPECT_FALSE(drawing_buffer_->MarkContentsChanged()); + EXPECT_EQ(gpu::SyncToken(), gl_->MostRecentlyWaitedSyncToken()); EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource, &release_callback)); + // PrepareTransferableResource() does not wait for any sync point. + EXPECT_EQ(gpu::SyncToken(), gl_->MostRecentlyWaitedSyncToken()); - // Pretend to release the resource. We should not wait for the sync token yet - // because the returned buffer is not recycled. gpu::SyncToken wait_sync_token; gl_->GenSyncTokenCHROMIUM(wait_sync_token.GetData()); - EXPECT_CALL(*gl_, WaitSyncTokenCHROMIUMMock(SyncTokenEq(wait_sync_token))) - .Times(0); release_callback->Run(wait_sync_token, false /* lostResource */); - testing::Mock::VerifyAndClearExpectations(gl_); + // m_drawingBuffer will wait for the sync point when recycling. + EXPECT_EQ(gpu::SyncToken(), gl_->MostRecentlyWaitedSyncToken()); - // The returned buffer will be recycled in PrepareTransferrableResource. Make - // sure we wait for the sync token now. - EXPECT_CALL(*gl_, WaitSyncTokenCHROMIUMMock(SyncTokenEq(wait_sync_token))) - .Times(1); EXPECT_TRUE(drawing_buffer_->MarkContentsChanged()); EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource, &release_callback)); - testing::Mock::VerifyAndClearExpectations(gl_); + // m_drawingBuffer waits for the sync point when recycling in + // PrepareTransferableResource(). + EXPECT_EQ(wait_sync_token, gl_->MostRecentlyWaitedSyncToken()); - // Release the resource and begin destruction. We will not wait on the sync - // token because the buffer is not reused. SharedImageInterface, however, will - // wait on the sync token before destruction. - gl_->GenSyncTokenCHROMIUM(wait_sync_token.GetData()); - EXPECT_CALL(*gl_, WaitSyncTokenCHROMIUMMock(SyncTokenEq(wait_sync_token))) - .Times(0); - release_callback->Run(wait_sync_token, false /* lostResource */); drawing_buffer_->BeginDestruction(); - testing::Mock::VerifyAndClearExpectations(gl_); + gl_->GenSyncTokenCHROMIUM(wait_sync_token.GetData()); + release_callback->Run(wait_sync_token, false /* lostResource */); + // m_drawingBuffer waits for the sync point because the destruction is in + // progress. + EXPECT_EQ(wait_sync_token, gl_->MostRecentlyWaitedSyncToken()); } class DrawingBufferImageChromiumTest : public DrawingBufferTest, @@ -401,7 +390,8 @@ std::make_unique<WebGraphicsContext3DProviderForTests>(std::move(gl)); GLES2InterfaceForTests* gl_ = static_cast<GLES2InterfaceForTests*>(provider->ContextGL()); - EXPECT_CALL(*gl_, CreateAndTexStorage2DSharedImageCHROMIUMMock(_)).Times(1); + image_id0_ = gl_->NextImageIdToBeCreated(); + EXPECT_CALL(*gl_, BindTexImage2DMock(image_id0_)).Times(1); bool gpu_compositing = true; drawing_buffer_ = DrawingBufferForTests::Create( std::move(provider), gpu_compositing, gl_, initial_size, @@ -422,141 +412,92 @@ TEST_F(DrawingBufferImageChromiumTest, VerifyResizingReallocatesImages) { GLES2InterfaceForTests* gl_ = drawing_buffer_->ContextGLForTests(); - viz::TestSharedImageInterface* sii = - drawing_buffer_->SharedImageInterfaceForTests(); - viz::TransferableResource resource; std::unique_ptr<viz::SingleReleaseCallback> release_callback; IntSize initial_size(kInitialWidth, kInitialHeight); IntSize alternate_size(kInitialWidth, kAlternateHeight); - // There should be currently one back buffer and therefore one SharedImage. - gpu::Mailbox mailbox1; - mailbox1.SetName(gl_->last_imported_shared_image()->name); - EXPECT_EQ(1u, sii->shared_image_count()); - EXPECT_TRUE(sii->CheckSharedImageExists(mailbox1)); - - // Produce one resource at size 100x100. This should create another buffer and - // therefore another SharedImage. - EXPECT_CALL(*gl_, CreateAndTexStorage2DSharedImageCHROMIUMMock(_)).Times(1); + GLuint image_id1 = gl_->NextImageIdToBeCreated(); + EXPECT_CALL(*gl_, BindTexImage2DMock(image_id1)).Times(1); + // Produce one resource at size 100x100. EXPECT_FALSE(drawing_buffer_->MarkContentsChanged()); EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource, &release_callback)); - EXPECT_EQ(static_cast<gfx::Size>(initial_size), sii->MostRecentSize()); + EXPECT_EQ(initial_size, gl_->MostRecentlyProducedSize()); EXPECT_TRUE(resource.is_overlay_candidate); EXPECT_EQ(static_cast<gfx::Size>(initial_size), resource.size); testing::Mock::VerifyAndClearExpectations(gl_); VerifyStateWasRestored(); - gpu::Mailbox mailbox2; - mailbox2.SetName(gl_->last_imported_shared_image()->name); - EXPECT_EQ(2u, sii->shared_image_count()); - EXPECT_TRUE(sii->CheckSharedImageExists(mailbox1)); - EXPECT_TRUE(sii->CheckSharedImageExists(mailbox2)); - EXPECT_EQ(mailbox2, resource.mailbox_holder.mailbox); - // Resize to 100x50. The current backbuffer must be destroyed. The exported - // resource should stay alive. A new backbuffer must be created. - EXPECT_CALL(*gl_, CreateAndTexStorage2DSharedImageCHROMIUMMock(_)).Times(1); + GLuint image_id2 = gl_->NextImageIdToBeCreated(); + EXPECT_CALL(*gl_, BindTexImage2DMock(image_id2)).Times(1); + EXPECT_CALL(*gl_, DestroyImageMock(image_id0_)).Times(1); + EXPECT_CALL(*gl_, ReleaseTexImage2DMock(image_id0_)).Times(1); + EXPECT_CALL(*gl_, DestroyImageMock(image_id1)).Times(1); + EXPECT_CALL(*gl_, ReleaseTexImage2DMock(image_id1)).Times(1); + // Resize to 100x50. drawing_buffer_->Resize(alternate_size); VerifyStateWasRestored(); - gpu::Mailbox mailbox3; - mailbox3.SetName(gl_->last_imported_shared_image()->name); - EXPECT_EQ(2u, sii->shared_image_count()); - EXPECT_FALSE(sii->CheckSharedImageExists(mailbox1)); - EXPECT_TRUE(sii->CheckSharedImageExists(mailbox2)); - EXPECT_TRUE(sii->CheckSharedImageExists(mailbox3)); - testing::Mock::VerifyAndClearExpectations(gl_); - - // Return the exported resource. Now it should get destroyed too. release_callback->Run(gpu::SyncToken(), false /* lostResource */); VerifyStateWasRestored(); - EXPECT_EQ(1u, sii->shared_image_count()); - EXPECT_FALSE(sii->CheckSharedImageExists(mailbox1)); - EXPECT_FALSE(sii->CheckSharedImageExists(mailbox2)); - EXPECT_TRUE(sii->CheckSharedImageExists(mailbox3)); + testing::Mock::VerifyAndClearExpectations(gl_); - // Produce a resource at the new size. - EXPECT_CALL(*gl_, CreateAndTexStorage2DSharedImageCHROMIUMMock(_)).Times(1); + GLuint image_id3 = gl_->NextImageIdToBeCreated(); + EXPECT_CALL(*gl_, BindTexImage2DMock(image_id3)).Times(1); + // Produce a resource at this size. EXPECT_TRUE(drawing_buffer_->MarkContentsChanged()); EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource, &release_callback)); - EXPECT_EQ(static_cast<gfx::Size>(alternate_size), sii->MostRecentSize()); + EXPECT_EQ(alternate_size, gl_->MostRecentlyProducedSize()); EXPECT_TRUE(resource.is_overlay_candidate); EXPECT_EQ(static_cast<gfx::Size>(alternate_size), resource.size); - gpu::Mailbox mailbox4; - mailbox4.SetName(gl_->last_imported_shared_image()->name); - EXPECT_EQ(2u, sii->shared_image_count()); - EXPECT_TRUE(sii->CheckSharedImageExists(mailbox3)); - EXPECT_TRUE(sii->CheckSharedImageExists(mailbox4)); - EXPECT_EQ(mailbox4, resource.mailbox_holder.mailbox); testing::Mock::VerifyAndClearExpectations(gl_); - // Reset to initial size. The exported resource has to stay alive, but the - // current back buffer must be destroyed and a new one with the right size - // must be created. - EXPECT_CALL(*gl_, CreateAndTexStorage2DSharedImageCHROMIUMMock(_)).Times(1); + GLuint image_id4 = gl_->NextImageIdToBeCreated(); + EXPECT_CALL(*gl_, BindTexImage2DMock(image_id4)).Times(1); + EXPECT_CALL(*gl_, DestroyImageMock(image_id2)).Times(1); + EXPECT_CALL(*gl_, ReleaseTexImage2DMock(image_id2)).Times(1); + EXPECT_CALL(*gl_, DestroyImageMock(image_id3)).Times(1); + EXPECT_CALL(*gl_, ReleaseTexImage2DMock(image_id3)).Times(1); + // Reset to initial size. drawing_buffer_->Resize(initial_size); VerifyStateWasRestored(); - gpu::Mailbox mailbox5; - mailbox5.SetName(gl_->last_imported_shared_image()->name); - EXPECT_EQ(2u, sii->shared_image_count()); - EXPECT_FALSE(sii->CheckSharedImageExists(mailbox3)); - EXPECT_TRUE(sii->CheckSharedImageExists(mailbox4)); - EXPECT_TRUE(sii->CheckSharedImageExists(mailbox5)); - testing::Mock::VerifyAndClearExpectations(gl_); - - // Return the exported resource. Now it will be destroyed too. release_callback->Run(gpu::SyncToken(), false /* lostResource */); VerifyStateWasRestored(); - EXPECT_EQ(1u, sii->shared_image_count()); - EXPECT_FALSE(sii->CheckSharedImageExists(mailbox3)); - EXPECT_FALSE(sii->CheckSharedImageExists(mailbox4)); - EXPECT_TRUE(sii->CheckSharedImageExists(mailbox5)); + testing::Mock::VerifyAndClearExpectations(gl_); + GLuint image_id5 = gl_->NextImageIdToBeCreated(); + EXPECT_CALL(*gl_, BindTexImage2DMock(image_id5)).Times(1); // Prepare another resource and verify that it's the correct size. - EXPECT_CALL(*gl_, CreateAndTexStorage2DSharedImageCHROMIUMMock(_)).Times(1); EXPECT_TRUE(drawing_buffer_->MarkContentsChanged()); EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource, &release_callback)); - EXPECT_EQ(static_cast<gfx::Size>(initial_size), sii->MostRecentSize()); + EXPECT_EQ(initial_size, gl_->MostRecentlyProducedSize()); EXPECT_TRUE(resource.is_overlay_candidate); EXPECT_EQ(static_cast<gfx::Size>(initial_size), resource.size); testing::Mock::VerifyAndClearExpectations(gl_); - gpu::Mailbox mailbox6; - mailbox6.SetName(gl_->last_imported_shared_image()->name); - EXPECT_EQ(2u, sii->shared_image_count()); - EXPECT_TRUE(sii->CheckSharedImageExists(mailbox5)); - EXPECT_TRUE(sii->CheckSharedImageExists(mailbox6)); - // Prepare one final resource and verify that it's the correct size. We should - // recycle the previously exported resource and avoid allocating a new - // SharedImage. + // Prepare one final resource and verify that it's the correct size. release_callback->Run(gpu::SyncToken(), false /* lostResource */); EXPECT_TRUE(drawing_buffer_->MarkContentsChanged()); EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource, &release_callback)); - EXPECT_EQ(static_cast<gfx::Size>(initial_size), sii->MostRecentSize()); + EXPECT_EQ(initial_size, gl_->MostRecentlyProducedSize()); EXPECT_TRUE(resource.is_overlay_candidate); EXPECT_EQ(static_cast<gfx::Size>(initial_size), resource.size); release_callback->Run(gpu::SyncToken(), false /* lostResource */); - EXPECT_EQ(2u, sii->shared_image_count()); - EXPECT_TRUE(sii->CheckSharedImageExists(mailbox5)); - EXPECT_TRUE(sii->CheckSharedImageExists(mailbox6)); + EXPECT_CALL(*gl_, DestroyImageMock(image_id5)).Times(1); + EXPECT_CALL(*gl_, ReleaseTexImage2DMock(image_id5)).Times(1); + EXPECT_CALL(*gl_, DestroyImageMock(image_id4)).Times(1); + EXPECT_CALL(*gl_, ReleaseTexImage2DMock(image_id4)).Times(1); drawing_buffer_->BeginDestruction(); - testing::Mock::VerifyAndClearExpectations(sii); - EXPECT_EQ(0u, sii->shared_image_count()); + testing::Mock::VerifyAndClearExpectations(gl_); } TEST_F(DrawingBufferImageChromiumTest, AllocationFailure) { GLES2InterfaceForTests* gl_ = drawing_buffer_->ContextGLForTests(); - viz::TestGpuMemoryBufferManager* gmb_manager = - static_cast<viz::TestGpuMemoryBufferManager*>( - Platform::Current()->GetGpuMemoryBufferManager()); - viz::TestSharedImageInterface* sii = - drawing_buffer_->SharedImageInterfaceForTests(); - viz::TransferableResource resource1; std::unique_ptr<viz::SingleReleaseCallback> release_callback1; viz::TransferableResource resource2; @@ -564,43 +505,33 @@ viz::TransferableResource resource3; std::unique_ptr<viz::SingleReleaseCallback> release_callback3; - // Request a resource. A SharedImage should already be created. Everything - // works as expected. - EXPECT_CALL(*gl_, CreateAndTexStorage2DSharedImageCHROMIUMMock(_)).Times(1); + // Request a resource. An image should already be created. Everything works + // as expected. + EXPECT_CALL(*gl_, BindTexImage2DMock(_)).Times(1); EXPECT_FALSE(drawing_buffer_->MarkContentsChanged()); EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource1, &release_callback1)); EXPECT_TRUE(resource1.is_overlay_candidate); - gpu::Mailbox mailbox1; - mailbox1.SetName(gl_->last_imported_shared_image()->name); - EXPECT_TRUE(sii->CheckSharedImageExists(mailbox1)); testing::Mock::VerifyAndClearExpectations(gl_); VerifyStateWasRestored(); - // Force GpuMemoryBuffer creation failure. Request another resource. It should + // Force image CHROMIUM creation failure. Request another resource. It should // still be provided, but this time with allowOverlay = false. - EXPECT_CALL(*gl_, CreateAndTexStorage2DSharedImageCHROMIUMMock(_)).Times(1); - gmb_manager->SetFailOnCreate(true); + gl_->SetCreateImageChromiumFail(true); EXPECT_TRUE(drawing_buffer_->MarkContentsChanged()); EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource2, &release_callback2)); EXPECT_FALSE(resource2.is_overlay_candidate); - gpu::Mailbox mailbox2; - mailbox2.SetName(gl_->last_imported_shared_image()->name); - EXPECT_TRUE(sii->CheckSharedImageExists(mailbox2)); VerifyStateWasRestored(); - // Check that if GpuMemoryBuffer allocation starts working again, resources - // are correctly created with allowOverlay = true. - EXPECT_CALL(*gl_, CreateAndTexStorage2DSharedImageCHROMIUMMock(_)).Times(1); - gmb_manager->SetFailOnCreate(false); + // Check that if image CHROMIUM starts working again, resources are + // correctly created with allowOverlay = true. + EXPECT_CALL(*gl_, BindTexImage2DMock(_)).Times(1); + gl_->SetCreateImageChromiumFail(false); EXPECT_TRUE(drawing_buffer_->MarkContentsChanged()); EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource3, &release_callback3)); EXPECT_TRUE(resource3.is_overlay_candidate); - gpu::Mailbox mailbox3; - mailbox3.SetName(gl_->last_imported_shared_image()->name); - EXPECT_TRUE(sii->CheckSharedImageExists(mailbox3)); testing::Mock::VerifyAndClearExpectations(gl_); VerifyStateWasRestored(); @@ -608,10 +539,10 @@ release_callback2->Run(gpu::SyncToken(), false /* lostResource */); release_callback3->Run(gpu::SyncToken(), false /* lostResource */); + EXPECT_CALL(*gl_, DestroyImageMock(_)).Times(3); + EXPECT_CALL(*gl_, ReleaseTexImage2DMock(_)).Times(3); drawing_buffer_->BeginDestruction(); - EXPECT_FALSE(sii->CheckSharedImageExists(mailbox1)); - EXPECT_FALSE(sii->CheckSharedImageExists(mailbox2)); - EXPECT_FALSE(sii->CheckSharedImageExists(mailbox3)); + testing::Mock::VerifyAndClearExpectations(gl_); } class DepthStencilTrackingGLES2Interface @@ -776,11 +707,10 @@ gpu::SyncToken wait_sync_token; gl_->GenSyncTokenCHROMIUM(wait_sync_token.GetData()); drawing_buffer_->SetIsHidden(true); - // m_drawingBuffer deletes resource immediately when hidden. - EXPECT_CALL(*gl_, WaitSyncTokenCHROMIUMMock(SyncTokenEq(wait_sync_token))) - .Times(0); release_callback->Run(wait_sync_token, false /* lostResource */); - testing::Mock::VerifyAndClearExpectations(gl_); + // m_drawingBuffer deletes resource immediately when hidden. + + EXPECT_EQ(wait_sync_token, gl_->MostRecentlyWaitedSyncToken()); drawing_buffer_->BeginDestruction(); }
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h index b6920cb6..d5e83b84 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h +++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h
@@ -7,7 +7,6 @@ #include "build/build_config.h" #include "cc/test/stub_decode_cache.h" -#include "components/viz/test/test_context_provider.h" #include "gpu/command_buffer/common/capabilities.h" #include "gpu/config/gpu_feature_info.h" #include "testing/gmock/include/gmock/gmock.h" @@ -59,16 +58,12 @@ sk_sp<SkColorSpace> color_space) override { return &image_decode_cache_; } - viz::TestSharedImageInterface* SharedImageInterface() override { - return &test_shared_image_interface_; - } private: cc::StubDecodeCache image_decode_cache_; std::unique_ptr<gpu::gles2::GLES2Interface> gl_; gpu::Capabilities capabilities_; gpu::GpuFeatureInfo gpu_feature_info_; - viz::TestSharedImageInterface test_shared_image_interface_; }; // The target to use when binding a texture to a Chromium image. @@ -178,11 +173,10 @@ break; } } - MOCK_METHOD1(WaitSyncTokenCHROMIUMMock, void(const GLbyte* sync_token)); + void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) override { memcpy(&most_recently_waited_sync_token_, sync_token, sizeof(most_recently_waited_sync_token_)); - WaitSyncTokenCHROMIUMMock(sync_token); } GLenum CheckFramebufferStatus(GLenum target) override { @@ -279,19 +273,6 @@ textures[i] = id++; } - MOCK_METHOD1(CreateAndTexStorage2DSharedImageCHROMIUMMock, - void(const GLbyte*)); - GLuint CreateAndTexStorage2DSharedImageCHROMIUM( - const GLbyte* mailbox) override { - CreateAndTexStorage2DSharedImageCHROMIUMMock(mailbox); - GLuint texture_id; - GenTextures(1, &texture_id); - last_imported_shared_image_.SetZero(); - last_imported_shared_image_.SetName( - reinterpret_cast<const gpu::Mailbox*>(mailbox)->name); - return texture_id; - } - // DrawingBuffer::Client implementation. bool DrawingBufferClientIsBoundForDraw() override { return !state_.draw_framebuffer_binding; @@ -370,10 +351,6 @@ saved_state_.pixel_pack_buffer_binding); } - gpu::Mailbox* last_imported_shared_image() { - return &last_imported_shared_image_; - } - private: std::map<GLenum, GLuint> bound_textures_; @@ -410,7 +387,6 @@ HashMap<GLuint, IntSize> texture_sizes_; HashMap<GLuint, IntSize> image_sizes_; HashMap<GLuint, GLuint> image_to_texture_map_; - gpu::Mailbox last_imported_shared_image_; }; class DrawingBufferForTests : public DrawingBuffer { @@ -467,11 +443,6 @@ return static_cast<GLES2InterfaceForTests*>(ContextGL()); } - viz::TestSharedImageInterface* SharedImageInterfaceForTests() { - return static_cast<viz::TestSharedImageInterface*>( - ContextProvider()->SharedImageInterface()); - } - bool* live_; int RecycledBitmapCount() { return recycled_bitmaps_.size(); }
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer.cc b/third_party/blink/renderer/platform/graphics/graphics_layer.cc index ac695a7f..4a1a259 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_layer.cc +++ b/third_party/blink/renderer/platform/graphics/graphics_layer.cc
@@ -96,6 +96,7 @@ rendering_context3d_(0), weak_ptr_factory_(this) { #if DCHECK_IS_ON() + DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); client.VerifyNotPainting(); #endif layer_ = cc::PictureLayer::Create(this);
diff --git a/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.cc b/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.cc index baed37d..29c7300 100644 --- a/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.cc +++ b/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.cc
@@ -32,21 +32,25 @@ bool EffectPaintPropertyNode::Changed( const PropertyTreeState& relative_to_state, const TransformPaintPropertyNode* transform_not_to_check) const { - auto* relative_effect = relative_to_state.Effect() - ? relative_to_state.Effect()->Unalias() - : nullptr; - if (transform_not_to_check) - transform_not_to_check = transform_not_to_check->Unalias(); - for (const auto* node = Unalias(); node && node != relative_effect; - node = node->Parent() ? node->Parent()->Unalias() : nullptr) { + auto* relative_effect = relative_to_state.Effect(); + auto* relative_transform = relative_to_state.Transform(); + + // Note that we can't unalias nodes in the loop conditions, since we need to + // check NodeChanged() function on aliased nodes as well (since the parenting + // might change). + for (const auto* node = this; node && node != relative_effect; + node = node->Parent()) { if (node->NodeChanged()) return true; - auto* local_transform = node->LocalTransformSpace() - ? node->LocalTransformSpace()->Unalias() - : nullptr; + + // We shouldn't check state on aliased nodes, other than NodeChanged(). + if (node->IsParentAlias()) + continue; + + auto* local_transform = node->LocalTransformSpace(); if (node->HasFilterThatMovesPixels() && local_transform != transform_not_to_check && - local_transform->Changed(*relative_to_state.Transform()->Unalias())) { + local_transform->Changed(*relative_transform)) { return true; } // We don't check for change of OutputClip here to avoid N^3 complexity.
diff --git a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc index 4cecc2c3..6a7e251 100644 --- a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc +++ b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc
@@ -697,4 +697,103 @@ FinishCycle(*artifact); } +TEST_P(RasterInvalidatorTest, AliasEffectParentChanges) { + RasterInvalidator invalidator(kNoopRasterInvalidation); + + CompositorFilterOperations filter; + filter.AppendOpacityFilter(0.5); + // Create an effect and an alias for that effect. + auto e1 = CreateFilterEffect(e0(), &t0(), &c0(), filter); + auto alias_effect = EffectPaintPropertyNode::CreateAlias(*e1); + + // The artifact has a chunk pointing to the alias. + PropertyTreeState layer_state(&t0(), &c0(), &e0()); + PropertyTreeState chunk_state(&t0(), &c0(), alias_effect.get()); + auto artifact = TestPaintArtifact().Chunk(0).Properties(chunk_state).Build(); + + invalidator.Generate(artifact, kDefaultLayerBounds, layer_state); + FinishCycle(*artifact); + + invalidator.SetTracksRasterInvalidations(true); + // Reparent the aliased effect, so the chunk doesn't change the actual alias + // node, but its parent is now different. + alias_effect->Update(e0(), EffectPaintPropertyNode::State{}); + + // We expect to get invalidations since the effect unaliased effect is + // actually different now. + invalidator.Generate(artifact, kDefaultLayerBounds, layer_state); + const auto& invalidations = TrackedRasterInvalidations(invalidator); + ASSERT_EQ(1u, invalidations.size()); + EXPECT_CHUNK_INVALIDATION(invalidations, 0, artifact->PaintChunks()[0], + PaintInvalidationReason::kPaintProperty); + FinishCycle(*artifact); +} + +TEST_P(RasterInvalidatorTest, NestedAliasEffectParentChanges) { + RasterInvalidator invalidator(kNoopRasterInvalidation); + + CompositorFilterOperations filter; + filter.AppendOpacityFilter(0.5); + // Create an effect and an alias for that effect. + auto e1 = CreateFilterEffect(e0(), &t0(), &c0(), filter); + auto alias_effect_1 = EffectPaintPropertyNode::CreateAlias(*e1); + auto alias_effect_2 = EffectPaintPropertyNode::CreateAlias(*alias_effect_1); + + // The artifact has a chunk pointing to the nested alias. + PropertyTreeState layer_state(&t0(), &c0(), &e0()); + PropertyTreeState chunk_state(&t0(), &c0(), alias_effect_2.get()); + auto artifact = TestPaintArtifact().Chunk(0).Properties(chunk_state).Build(); + + invalidator.Generate(artifact, kDefaultLayerBounds, layer_state); + FinishCycle(*artifact); + + invalidator.SetTracksRasterInvalidations(true); + // Reparent the parent aliased effect, so the chunk doesn't change the actual + // alias node, but its parent is now different, this also ensures that the + // nested alias is unchanged. + alias_effect_1->Update(e0(), EffectPaintPropertyNode::State{}); + + // We expect to get invalidations since the effect unaliased effect is + // actually different now. + invalidator.Generate(artifact, kDefaultLayerBounds, layer_state); + const auto& invalidations = TrackedRasterInvalidations(invalidator); + ASSERT_EQ(1u, invalidations.size()); + EXPECT_CHUNK_INVALIDATION(invalidations, 0, artifact->PaintChunks()[0], + PaintInvalidationReason::kPaintProperty); + FinishCycle(*artifact); +} + +TEST_P(RasterInvalidatorTest, EffectWithAliasTransformWhoseParentChanges) { + RasterInvalidator invalidator(kNoopRasterInvalidation); + + auto t1 = CreateTransform(t0(), TransformationMatrix().Scale(5)); + auto alias_transform = TransformPaintPropertyNode::CreateAlias(*t1); + + CompositorFilterOperations filter; + filter.AppendBlurFilter(0); + // Create an effect and an alias for that effect. + auto e1 = CreateFilterEffect(e0(), alias_transform.get(), &c0(), filter); + + // The artifact has a chunk pointing to the alias. + PropertyTreeState layer_state(&t0(), &c0(), &e0()); + PropertyTreeState chunk_state(&t0(), &c0(), e1.get()); + auto artifact = TestPaintArtifact().Chunk(0).Properties(chunk_state).Build(); + + invalidator.Generate(artifact, kDefaultLayerBounds, layer_state); + FinishCycle(*artifact); + + invalidator.SetTracksRasterInvalidations(true); + // Reparent the aliased effect, so the chunk doesn't change the actual alias + // node, but its parent is now different. + alias_transform->Update(t0(), TransformPaintPropertyNode::State{}); + + // We expect to get invalidations since the effect unaliased effect is + // actually different now. + invalidator.Generate(artifact, kDefaultLayerBounds, layer_state); + const auto& invalidations = TrackedRasterInvalidations(invalidator); + ASSERT_EQ(1u, invalidations.size()); + EXPECT_CHUNK_INVALIDATION(invalidations, 0, artifact->PaintChunks()[0], + PaintInvalidationReason::kPaintProperty); + FinishCycle(*artifact); +} } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/platform_paint_worklet_input.h b/third_party/blink/renderer/platform/graphics/platform_paint_worklet_input.h new file mode 100644 index 0000000..05d0c4d --- /dev/null +++ b/third_party/blink/renderer/platform/graphics/platform_paint_worklet_input.h
@@ -0,0 +1,41 @@ +// 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_GRAPHICS_PLATFORM_PAINT_WORKLET_INPUT_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PLATFORM_PAINT_WORKLET_INPUT_H_ + +#include "cc/paint/paint_worklet_input.h" + +namespace blink { + +class PLATFORM_EXPORT PlatformPaintWorkletInput : public cc::PaintWorkletInput { + public: + PlatformPaintWorkletInput(const std::string& name, + const FloatSize& container_size, + float effective_zoom) + : name_(name), + container_size_(container_size), + effective_zoom_(effective_zoom) {} + + ~PlatformPaintWorkletInput() override = default; + + // PaintWorkletInput implementation + gfx::SizeF GetSize() const override { + return gfx::SizeF(container_size_.Width(), container_size_.Height()); + } + + const std::string& Name() const { return name_; } + const FloatSize& ContainerSize() const { return container_size_; } + float EffectiveZoom() const { return effective_zoom_; } + + private: + std::string name_; + FloatSize container_size_; + float effective_zoom_; + // TODO(crbug.com/895579): add a cross thread style map. +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHIC_PLATFORM_PAINT_WORKLET_INPUT_H_
diff --git a/third_party/blink/renderer/platform/graphics/test/DEPS b/third_party/blink/renderer/platform/graphics/test/DEPS index 09a7050..3a676d7 100644 --- a/third_party/blink/renderer/platform/graphics/test/DEPS +++ b/third_party/blink/renderer/platform/graphics/test/DEPS
@@ -1,6 +1,5 @@ include_rules = [ "+components/viz/test/test_gpu_memory_buffer_manager.h", - "+components/viz/test/test_context_provider.h", "+gpu/command_buffer/client/gles2_interface_stub.h", - "+gpu/config/gpu_feature_info.h", + "+gpu/config/gpu_feature_info.h" ]
diff --git a/third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h b/third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h index d0d7906..54e63456 100644 --- a/third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h +++ b/third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h
@@ -7,7 +7,6 @@ #include "cc/test/stub_decode_cache.h" #include "cc/tiles/image_decode_cache.h" -#include "components/viz/test/test_context_provider.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/common/capabilities.h" #include "gpu/config/gpu_feature_info.h" @@ -59,14 +58,10 @@ sk_sp<SkColorSpace> color_space) override { return image_decode_cache_; } - viz::TestSharedImageInterface* SharedImageInterface() override { - return &test_shared_image_interface_; - } private: cc::StubDecodeCache stub_image_decode_cache_; - viz::TestSharedImageInterface test_shared_image_interface_; gpu::gles2::GLES2Interface* gl_; sk_sp<GrContext> gr_context_; gpu::Capabilities capabilities_;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index e5a88f6..2448fe2 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1366,6 +1366,10 @@ status: "experimental", }, { + name: "WebBluetoothScanning", + status: "test", + }, + { name: "WebFontsCacheAwareTimeoutAdaptation", status: "experimental", },
diff --git a/third_party/blink/tools/blinkpy/third_party/README.chromium b/third_party/blink/tools/blinkpy/third_party/README.chromium index 37795382..471794f 100644 --- a/third_party/blink/tools/blinkpy/third_party/README.chromium +++ b/third_party/blink/tools/blinkpy/third_party/README.chromium
@@ -32,7 +32,7 @@ Name: web-platform-tests - Test Suites for Web Platform specifications Short Name: wpt URL: https://github.com/web-platform-tests/wpt/ -Version: bbed5ce4e3696466e0766875dc23e8da5681c964 +Version: 23ce30a85c115ea9247e4ef7e3e0d108110a08cd License: LICENSES FOR W3C TEST SUITES (http://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright.html) License File: wpt/wpt/LICENSE.md Security Critical: no
diff --git a/third_party/blink/tools/blinkpy/third_party/wpt/checkout.sh b/third_party/blink/tools/blinkpy/third_party/wpt/checkout.sh index af1a8799..7a4fe6c0 100755 --- a/third_party/blink/tools/blinkpy/third_party/wpt/checkout.sh +++ b/third_party/blink/tools/blinkpy/third_party/wpt/checkout.sh
@@ -9,7 +9,7 @@ TARGET_DIR=$DIR/wpt REMOTE_REPO="https://chromium.googlesource.com/external/github.com/web-platform-tests/wpt.git" -WPT_HEAD=bbed5ce4e3696466e0766875dc23e8da5681c964 +WPT_HEAD=23ce30a85c115ea9247e4ef7e3e0d108110a08cd function clone { # Remove existing repo if already exists.
diff --git a/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/manifest/manifest.py b/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/manifest/manifest.py index bcf3de3..2777109 100644 --- a/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/manifest/manifest.py +++ b/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/manifest/manifest.py
@@ -11,8 +11,10 @@ try: import ujson as json + JSON_LIBRARY = 'ujson' except ImportError: import json + JSON_LIBRARY = 'json' CURRENT_VERSION = 5 @@ -473,5 +475,12 @@ if not os.path.exists(dir_name): os.makedirs(dir_name) with open(manifest_path, "wb") as f: - json.dump(manifest.to_json(), f, sort_keys=True, indent=1) + if JSON_LIBRARY == 'ujson': + # ujson does not support the separators flag. + json.dump(manifest.to_json(), f, sort_keys=True, indent=1) + else: + # Use ',' instead of the default ', ' separator to prevent trailing + # spaces: https://docs.python.org/2/library/json.html#json.dump + json.dump(manifest.to_json(), f, + sort_keys=True, indent=1, separators=(',', ': ')) f.write("\n")
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint index be4de0e0..3d304978 100644 --- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint +++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint
@@ -126,13 +126,13 @@ Bug(none) compositing/overflow/scrollbar-layer-placement.html [ Failure ] Bug(none) compositing/overflow/scrollbar-layer-placement-negative-z-index-child.html [ Failure ] Bug(none) compositing/overflow/scrolling-content-clip-to-viewport.html [ Failure ] -crbug.com/667946 compositing/overflow/scrolls-with-respect-to-nested.html [ Failure Crash ] -crbug.com/667946 compositing/overflow/scrolls-with-respect-to-transform.html [ Failure Crash ] -crbug.com/667946 compositing/overflow/scrolls-with-respect-to.html [ Failure Crash ] +crbug.com/667946 compositing/overflow/scrolls-with-respect-to-nested.html [ Failure ] +crbug.com/667946 compositing/overflow/scrolls-with-respect-to-transform.html [ Failure ] +crbug.com/667946 compositing/overflow/scrolls-with-respect-to.html [ Failure ] Bug(none) compositing/overflow/textarea-scroll-touch.html [ Failure ] Bug(none) compositing/overflow/universal-accelerated-overflow-scroll.html [ Failure ] -Bug(none) compositing/reflections/deeply-nested-reflections.html [ Failure Crash ] -Bug(none) compositing/reflections/nested-reflection-mask-change.html [ Failure Crash ] +Bug(none) compositing/reflections/deeply-nested-reflections.html [ Failure ] +Bug(none) compositing/reflections/nested-reflection-mask-change.html [ Failure ] Bug(none) compositing/rtl/rtl-absolute-overflow-scrolled.html [ Failure Crash ] Bug(none) compositing/rtl/rtl-absolute-overflow.html [ Failure Crash ] Bug(none) compositing/rtl/rtl-fixed-overflow-scrolled.html [ Failure Crash ]
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG index cec20655..0f08844 100644 --- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
@@ -62,6 +62,7 @@ crbug.com/591099 css3/flexbox/intrinsic-width-orthogonal-writing-mode.html [ Failure ] crbug.com/591099 css3/selectors3/xml/css3-modsel-61.xml [ Failure Pass ] crbug.com/591099 css3/selectors3/xml/css3-modsel-62.xml [ Failure Pass ] +crbug.com/591099 css3/selectors3/xml/css3-modsel-91.xml [ Failure Pass ] crbug.com/591099 css3/selectors3/xml/css3-modsel-93.xml [ Failure Pass ] crbug.com/591099 editing/selection/paint-hyphen.html [ Pass ] crbug.com/591099 external/wpt/css/CSS2/abspos/abspos-in-block-in-inline-in-relpos-inline.html [ Failure ] @@ -77,7 +78,7 @@ crbug.com/591099 external/wpt/css/CSS2/text/white-space-mixed-003.xht [ Pass ] crbug.com/714962 external/wpt/css/css-fonts/font-features-across-space-1.html [ Pass ] crbug.com/714962 external/wpt/css/css-fonts/font-features-across-space-3.html [ Pass ] -crbug.com/591099 external/wpt/css/css-namespaces/syntax-007.xml [ Failure Pass ] +crbug.com/591099 external/wpt/css/css-namespaces/syntax-007.xml [ Failure ] crbug.com/591099 external/wpt/css/css-position/static-position/htb-ltr-rtl.tentative.html [ Pass ] crbug.com/591099 external/wpt/css/css-position/static-position/htb-rtl-ltr.tentative.html [ Pass ] crbug.com/591099 external/wpt/css/css-position/static-position/htb-rtl-rtl.html [ Pass ] @@ -102,6 +103,7 @@ crbug.com/40634 external/wpt/css/css-text/white-space/trailing-space-before-br-001.html [ Pass ] crbug.com/591099 external/wpt/css/css-text/white-space/white-space-pre-wrap-trailing-spaces-001.html [ Failure ] crbug.com/591099 external/wpt/css/css-text/word-break/word-break-break-all-004.html [ Pass ] +crbug.com/591099 external/wpt/css/css-text/word-break/word-break-keep-all-003.html [ Pass ] crbug.com/591099 external/wpt/css/css-ui/text-overflow-010.html [ Pass ] crbug.com/893550 external/wpt/css/css-ui/text-overflow-015.html [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vlr-003.xht [ Pass ] @@ -225,7 +227,7 @@ crbug.com/591099 external/wpt/fetch/api/redirect/redirect-count.any.html [ Pass ] crbug.com/591099 external/wpt/fetch/api/redirect/redirect-count.any.worker.html [ Pass ] crbug.com/591099 external/wpt/fetch/api/request/request-keepalive-quota.html?include=slow-2 [ Pass ] -crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Failure ] +crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Failure Pass ] crbug.com/591099 external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html [ Pass ] crbug.com/591099 external/wpt/html/interaction/focus/sequential-focus-navigation-and-the-tabindex-attribute/focus-tabindex-positive.html [ Timeout ] crbug.com/850504 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical.html [ Failure ] @@ -301,6 +303,21 @@ crbug.com/591099 virtual/android/rootscroller/set-root-scroller.html [ Pass ] crbug.com/591099 virtual/android/rootscroller/set-rootscroller-before-load.html [ Pass ] crbug.com/591099 virtual/android/url-bar/bottom-and-top-fixed-sticks-to-top.html [ Failure ] +crbug.com/591099 virtual/bidi-caret-affinity/editing/pasteboard/copy-paste-white-space.html [ Pass ] +crbug.com/591099 virtual/bidi-caret-affinity/editing/selection/click-in-focusable-link-should-not-clear-selection.html [ Crash ] +crbug.com/591099 virtual/bidi-caret-affinity/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-ltr-mixed.html [ Crash ] +crbug.com/591099 virtual/bidi-caret-affinity/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping-rtl-mixed.html [ Crash ] +crbug.com/591099 virtual/bidi-caret-affinity/editing/selection/dont-select-text-overflow-ellipsis-when-wrapping.html [ Crash ] +crbug.com/591099 virtual/bidi-caret-affinity/editing/selection/doubleclick-whitespace-crash.html [ Crash ] +crbug.com/591099 virtual/bidi-caret-affinity/editing/selection/legal-positions.html [ Crash ] +crbug.com/591099 virtual/bidi-caret-affinity/editing/selection/modify_extend/extend_by_character.html [ Pass ] +crbug.com/591099 virtual/bidi-caret-affinity/editing/selection/paint-hyphen.html [ Crash ] +crbug.com/591099 virtual/bidi-caret-affinity/editing/selection/select-text-overflow-ellipsis-mixed-in-ltr-2.html [ Crash ] +crbug.com/591099 virtual/bidi-caret-affinity/editing/selection/select-text-overflow-ellipsis-mixed-in-ltr.html [ Crash ] +crbug.com/591099 virtual/bidi-caret-affinity/editing/selection/select-text-overflow-ellipsis-mixed-in-rtl-2.html [ Crash ] +crbug.com/591099 virtual/bidi-caret-affinity/editing/selection/select-text-overflow-ellipsis-mixed-in-rtl.html [ Crash ] +crbug.com/591099 virtual/bidi-caret-affinity/editing/selection/select-text-overflow-ellipsis.html [ Crash ] +crbug.com/591099 virtual/bidi-caret-affinity/editing/selection/word-granularity.html [ Crash ] crbug.com/916511 virtual/composite-after-paint/paint/background/scrolling-background-with-negative-z-child.html [ Failure ] crbug.com/591099 virtual/composite-after-paint/paint/invalidation/box/margin.html [ Failure Pass ] crbug.com/591099 virtual/display-lock/display-lock/lock-before-append/measure-and-remove.html [ Failure ]
diff --git a/third_party/blink/web_tests/LeakExpectations b/third_party/blink/web_tests/LeakExpectations index d58aca11..67eac970 100644 --- a/third_party/blink/web_tests/LeakExpectations +++ b/third_party/blink/web_tests/LeakExpectations
@@ -67,6 +67,9 @@ crbug.com/836278 [ Linux ] external/wpt/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.html [ Pass Leak ] crbug.com/836278 [ Linux ] virtual/threaded/external/wpt/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.html [ Pass Leak ] +# Moved from TestExpectations (Sheriff 2018-05-31) +crbug.com/848354 [ Linux ] plugins/fullscreen-plugins-dont-reload.html [ Pass Leak ] + # Sheriff 2018-07-10 # Test flaking on Linux Trusty Leak crbug.com/862029 [ Linux ] http/tests/devtools/tracing/timeline-misc/timeline-window-filter.js [ Pass Leak ] @@ -89,6 +92,9 @@ crbug.com/733494 [ Linux ] media/autoplay/document-user-activation.html [ Pass Leak ] crbug.com/733494 [ Linux ] virtual/video-surface-layer/media/autoplay/document-user-activation.html [ Pass Leak ] +# Sheriff 2018-12-20 +crbug.com/916893 [ Linux ] virtual/bidi-caret-affinity/editing/pasteboard/drag-drop-iframe-refresh-crash.html [ Pass Leak ] + ########################################################################### # WARNING: Memory leaks must be fixed asap. Sheriff is expected to revert # # culprit CLs instead of suppressing the leaks. If you have any question, #
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index 1c61558..31ba3a6 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -43,9 +43,20 @@ [ Linux ] virtual/mouseevent_fractional/fast/events/inputevents/inputevent-yank.html [ WontFix ] [ Win ] virtual/user-activation-v2/fast/events/inputevents/inputevent-yank.html [ WontFix ] [ Linux ] virtual/user-activation-v2/fast/events/inputevents/inputevent-yank.html [ WontFix ] + [ Win ] virtual/bidi-caret-affinity/editing/pasteboard/emacs-cntl-y-001.html [ WontFix ] + [ Linux ] virtual/bidi-caret-affinity/editing/pasteboard/emacs-cntl-y-001.html [ WontFix ] + [ Win ] virtual/bidi-caret-affinity/editing/pasteboard/emacs-ctrl-a-k-y.html [ WontFix ] + [ Linux ] virtual/bidi-caret-affinity/editing/pasteboard/emacs-ctrl-a-k-y.html [ WontFix ] + [ Win ] virtual/bidi-caret-affinity/editing/pasteboard/emacs-ctrl-k-with-move.html [ WontFix ] + [ Linux ] virtual/bidi-caret-affinity/editing/pasteboard/emacs-ctrl-k-with-move.html [ WontFix ] + [ Win ] virtual/bidi-caret-affinity/editing/pasteboard/emacs-ctrl-k-y-001.html [ WontFix ] + [ Linux ] virtual/bidi-caret-affinity/editing/pasteboard/emacs-ctrl-k-y-001.html [ WontFix ] + [ Win ] virtual/bidi-caret-affinity/editing/input/emacs-ctrl-o.html [ WontFix ] + [ Linux ] virtual/bidi-caret-affinity/editing/input/emacs-ctrl-o.html [ WontFix ] # Chrome Mac doesn't support Ctrl+Up/Down key-bindings. [ Mac ] editing/input/ctrl-up-down.html [ WontFix ] +[ Mac ] virtual/bidi-caret-affinity/editing/input/ctrl-up-down.html [ WontFix ] # Chrome uses different keyboard accelerators from those used by Safari, so # this test will always fail. @@ -93,6 +104,7 @@ [ Mac ] fast/events/menu-key-context-menu-position.html [ WontFix ] [ Mac ] fast/events/menu-key-context-menu-reveal-focus.html [ WontFix ] [ Mac ] fast/events/menu-key-context-menu.html [ WontFix ] +[ Mac ] virtual/bidi-caret-affinity/editing/spelling/spelling-on-context-menu-key.html [ WontFix ] [ Mac ] virtual/mouseevent_fractional/fast/events/context-menu-key-shift-f10-modifiers.html [ WontFix ] [ Mac ] virtual/mouseevent_fractional/fast/events/context-menu-key-shift-f10-prevent-default.html [ WontFix ] [ Mac ] virtual/mouseevent_fractional/fast/events/contextmenu-follows-focus.html [ WontFix ] @@ -125,6 +137,12 @@ [ Win ] fast/text/international/draw-complex-text-from-to.html [ WontFix ] [ Mac ] svg/text/text-with-geometric-precision.svg [ WontFix ] [ Win ] svg/text/text-with-geometric-precision.svg [ WontFix ] + [ Mac ] virtual/bidi-caret-affinity/editing/input/linux_ltr_composition_underline.html [ WontFix ] + [ Win ] virtual/bidi-caret-affinity/editing/input/linux_ltr_composition_underline.html [ WontFix ] + [ Mac ] virtual/bidi-caret-affinity/editing/input/linux_rtl_composition_underline.html [ WontFix ] + [ Win ] virtual/bidi-caret-affinity/editing/input/linux_rtl_composition_underline.html [ WontFix ] + [ Mac ] virtual/bidi-caret-affinity/editing/selection/linux_selection_color.html [ WontFix ] + [ Win ] virtual/bidi-caret-affinity/editing/selection/linux_selection_color.html [ WontFix ] # Mac has different fallback behavior so that this test won't work there [ Mac ] fast/text/font-cachekey.html [ WontFix ]
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests index 6c2e7f7..f4c7b767 100644 --- a/third_party/blink/web_tests/SlowTests +++ b/third_party/blink/web_tests/SlowTests
@@ -153,6 +153,7 @@ # FIXME: These tests might still be buggy and time out. They were marked as Slow on 9/20/2013. # Double-check the data after they've been running another week or so. crbug.com/245154 editing/selection/modify_move/move-by-character-brute-force.html [ Slow ] +crbug.com/245154 virtual/bidi-caret-affinity/editing/selection/modify_move/move-by-character-brute-force.html [ Slow ] # This test takes 5+ seconds as intended because it tests connection throttling. crbug.com/459377 http/tests/websocket/multiple-connections-throttled.html [ Slow ] @@ -1576,7 +1577,6 @@ crbug.com/912364 [ Mac ] virtual/user-activation-v2/fast/events/no-fake-mousemove.html [ Slow ] crbug.com/914981 [ Mac ] media/controls/overflow-menu-pointer-selection.html [ Slow ] -crbug.com/914981 [ Mac ] virtual/fractional_scrolling/fast/scrolling/overflow-scrollability.html [ Slow ] crbug.com/914981 [ Mac ] virtual/mouseevent_fractional/fast/events/no-fake-mousemove.html [ Slow ] crbug.com/914981 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/overflow-menu-pointer-selection.html [ Slow ] crbug.com/914981 [ Mac ] virtual/video-surface-layer/media/controls/overflow-menu-pointer-selection.html [ Slow ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index a273619..03615dc9f 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -634,6 +634,11 @@ crbug.com/885175 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/grid-abspos-staticpos-justify-self-vertWM-003.html [ Failure ] crbug.com/885175 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/align3/grid-abspos-staticpos-justify-self-vertWM-004.html [ Failure ] +crbug.com/855009 external/wpt/workers/semantics/structured-clone/dedicated.html [ Skip ] +crbug.com/855009 external/wpt/workers/semantics/structured-clone/shared.htm [ Skip ] +crbug.com/855009 virtual/omt-worker-fetch/external/wpt/workers/semantics/structured-clone/dedicated.html [ Skip ] +crbug.com/855009 virtual/omt-worker-fetch/external/wpt/workers/semantics/structured-clone/shared.htm [ Skip ] + # ====== Layout team owned tests to here ====== # ====== LayoutNG-only failures from here ====== @@ -1810,6 +1815,227 @@ # ====== LayoutNG-only failures until here ====== +# ====== Bidi caret affinity failures from here ====== + +### Tests already failing/flaky without the flag +crbug.com/892772 [ Mac ] virtual/bidi-caret-affinity/editing/caret/caret-painting-low-dpi.html [ Failure Pass ] +crbug.com/764489 virtual/bidi-caret-affinity/editing/execCommand/format-block-multiple-paragraphs-in-pre.html [ Failure ] +crbug.com/764489 virtual/bidi-caret-affinity/editing/execCommand/format-block-multiple-paragraphs.html [ Failure ] +crbug.com/774229 virtual/bidi-caret-affinity/editing/pasteboard/copy-paste-white-space.html [ Failure ] +crbug.com/821455 virtual/bidi-caret-affinity/editing/pasteboard/drag-files-to-editable-element.html [ Failure ] +crbug.com/891427 virtual/bidi-caret-affinity/editing/pasteboard/drop-text-without-selection.html [ Pass Failure Timeout Crash ] +crbug.com/891427 virtual/bidi-caret-affinity/editing/selection/drag-in-iframe.html [ Failure ] +crbug.com/900060 virtual/bidi-caret-affinity/editing/selection/mixed-editability-8.html [ Failure ] +crbug.com/636424 virtual/bidi-caret-affinity/editing/selection/modify_move/move-by-word-visually-crash-test-5.html [ Pass Timeout ] +crbug.com/851812 virtual/bidi-caret-affinity/editing/selection/paint-hyphen.html [ Failure ] +crbug.com/725470 virtual/bidi-caret-affinity/editing/shadow/doubleclick-on-meter-in-shadow-crash.html [ Crash Failure ] + +### True failures start from here + +### virtual/bidi-caret-affinity/editing/caret/ +crbug.com/894651 virtual/bidi-caret-affinity/editing/caret/caret-direction-auto.html [ Failure ] + +### virtual/bidi-caret-affinity/editing/inserting/ +crbug.com/894651 virtual/bidi-caret-affinity/editing/inserting/caret-position.html [ Failure ] + +### virtual/bidi-caret-affinity/editing/selection/ +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/caret-at-bidi-boundary.html [ Failure Timeout ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/caret-bidi-first-and-last-letters.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/caret-ltr-2-left.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/caret-ltr-2.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/caret-rtl-2-left.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/caret-rtl-2.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/css-pseudo-element.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/offset-from-point-complex-scripts.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/offset-from-point.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/select-bidi-run.html [ Failure ] + +### virtual/bidi-caret-affinity/editing/selection/modify_extend/ +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_extend/extend_by_character.html [ Failure ] + +### virtual/bidi-caret-affinity/editing/selection/modify_move/ +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move-by-word-visually-mac.html [ Timeout ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move-by-word-visually-multi-space.html [ Timeout ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move-by-word-visually-single-space-inline-element.html [ Timeout ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move-by-word-visually-single-space-one-element.html [ Timeout ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move-by-word-visually-wrong-left-right.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_01_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_02_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_03_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_04_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_05_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_05_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_06_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_06_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_07_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_07_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_08_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_08_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_09_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_09_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_10_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_10_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_11_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_11_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_12_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_12_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_13_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_13_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_14_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_14_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_15_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_15_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_16_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_16_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_17_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_17_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_18_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_18_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_19_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_19_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_20_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_20_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_21_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_21_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_22_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_22_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_23_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_24_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_25_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_25_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_26_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_26_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_27_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_28_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_29_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_29_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_30_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_30_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_31_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_31_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_32_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_32_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_33_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_33_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_34_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_34_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_35_ltr.html [ Crash Timeout ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_35_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_36_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_36_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_37_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_37_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_38_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_38_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_39_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_39_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_40_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_40_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_41_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_42_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_43_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_43_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_word_01_rtl_multi_line.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_word_02_rtl_multi_line.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_word_03_ltr_multi_line.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_word_04_ltr_multi_line.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_word_05_ltr_multi_line.html [ Timeout ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_word_05_rtl_multi_line.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_word_06_ltr_multi_line.html [ Timeout ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_word_06_rtl_multi_line.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_word_07_rtl_multi_line.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_word_08_rtl_multi_line.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_word_09_rtl_multi_line.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_01_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_02_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_03_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_04_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_05_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_05_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_06_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_06_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_07_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_07_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_08_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_08_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_09_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_09_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_10_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_10_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_11_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_11_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_12_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_12_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_13_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_15_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_15_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_16_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_16_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_17_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_17_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_18_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_18_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_19_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_19_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_20_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_20_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_21_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_21_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_22_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_22_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_23_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_24_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_25_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_25_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_26_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_26_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_27_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_28_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_29_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_29_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_30_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_30_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_31_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_31_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_32_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_32_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_33_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_33_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_34_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_34_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_35_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_35_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_36_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_36_rtl.html [ Crash Timeout ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_37_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_37_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_38_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_38_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_39_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_39_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_40_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_40_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_41_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_42_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_43_ltr.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_43_rtl.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_word_01_rtl_multi_line.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_word_02_rtl_multi_line.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_word_03_ltr_multi_line.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_word_04_ltr_multi_line.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_word_05_ltr_multi_line.html [ Failure Timeout ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_word_05_rtl_multi_line.html [ Timeout ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_word_06_ltr_multi_line.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_word_06_rtl_multi_line.html [ Timeout ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_word_07_rtl_multi_line.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_word_08_rtl_multi_line.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_word_09_rtl_multi_line.html [ Failure ] + +### virtual/bidi-caret-affinity/editing/style/ +crbug.com/894651 virtual/bidi-caret-affinity/editing/style/text-indent.html [ Failure ] + +# ====== Bidi caret affinity failures until here ====== + ### sheriff 2018-05-28 crbug.com/840238 http/tests/devtools/elements/shadow/shadow-distribution.js [ Failure ] @@ -3006,6 +3232,9 @@ crbug.com/893480 external/wpt/infrastructure/testdriver/actions/multiDevice.html [ Failure Timeout ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCTrackEvent-fire.html [ Timeout ] +crbug.com/626703 external/wpt/css/filter-effects/filter-subregion-01.html [ Failure ] +crbug.com/626703 external/wpt/webrtc/RTCTrackEvent-fire.html [ Timeout ] crbug.com/626703 virtual/layout_ng_experimental/external/wpt/css/css-multicol/multicol-span-all-005.html [ Failure ] crbug.com/626703 external/wpt/css/css-multicol/multicol-span-all-005.html [ Failure ] crbug.com/626703 [ Android ] external/wpt/css/css-layout-api/auto-block-size-absolute.https.html [ Failure ] @@ -4352,13 +4581,8 @@ # ====== End of display: contents tests ====== -crbug.com/676229 [ Win ] plugins/mouse-click-plugin-clears-selection.html [ Failure Pass ] -crbug.com/676229 [ Linux ] plugins/mouse-click-plugin-clears-selection.html [ Failure Pass ] -crbug.com/676229 [ Mac ] plugins/mouse-click-plugin-clears-selection.html [ Failure Pass ] -crbug.com/736333 [ Win ] plugins/iframe-plugin-bgcolor.html [ Failure Pass ] -crbug.com/736333 [ Linux ] plugins/iframe-plugin-bgcolor.html [ Failure Pass ] -crbug.com/742670 [ Mac ] plugins/iframe-plugin-bgcolor.html [ Failure Pass ] - +crbug.com/676229 plugins/mouse-click-plugin-clears-selection.html [ Failure Pass ] +crbug.com/742670 plugins/iframe-plugin-bgcolor.html [ Failure Pass ] crbug.com/780398 [ Mac ] plugins/mouse-capture-inside-shadow.html [ Failure Pass ] crbug.com/678346 [ Debug ] fast/dom/shadow/selections-in-shadow.html [ Pass Timeout ] @@ -4886,6 +5110,7 @@ crbug.com/793771 [ Mac ] media/controls/modern/scrubbing.html [ Skip ] crbug.com/793771 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/scrubbing.html [ Skip ] crbug.com/914981 [ Mac ] virtual/video-surface-layer/media/controls/modern/scrubbing.html [ Skip ] +crbug.com/916902 [ Mac ] virtual/fractional_scrolling/fast/scrolling/overflow-scrollability.html [ Skip ] # Different paths may have different anti-aliasing pixels 2018-02-21 skbug.com/7641 external/wpt/css/css-paint-api/paint2d-paths.https.html [ Failure Pass ] @@ -5139,7 +5364,6 @@ crbug.com/843135 virtual/gpu/fast/canvas/canvas-arc-circumference-fill.html [ Pass Failure ] # Sheriff 2018-05-31 -crbug.com/848354 [ Linux ] plugins/fullscreen-plugins-dont-reload.html [ Skip ] crbug.com/848398 http/tests/devtools/oopif/oopif-performance-cpu-profiles.js [ Pass Timeout Failure ] # Sheriff 2018-06-01 @@ -5714,6 +5938,7 @@ # Sheriff 2018-12-07 crbug.com/912821 [ Mac ] virtual/threaded/http/tests/devtools/tracing/user-timing.js [ Pass Failure ] +crbug.com/912821 [ Mac ] http/tests/devtools/tracing/user-timing.js [ Pass Failure ] crbug.com/913170 compositing/layer-creation/fixed-position-in-fixed-overflow.html [ Crash Pass ] crbug.com/913173 fast/backgrounds/background-svg-scaling-zoom.html [ Failure Pass ] @@ -5737,11 +5962,17 @@ crbug.com/891155 virtual/user-activation-v2/fast/events/middleClickAutoscroll-event-fired.html [ Skip ] crbug.com/913931 [ Mac10.11 ] external/wpt/css/css-layout-api/auto-block-size-absolute.https.html [ Pass Failure ] +# Sheriff 2018-12-19 +crbug.com/915862 [ Android ] webmidi/permission.html [ Pass Failure ] + # These tests will fail until upstream v8 changes are landed. crbug.com/v8/8381 http/tests/devtools/coverage/coverage-repeated.js [ Pass Failure ] crbug.com/v8/8381 http/tests/devtools/coverage/coverage-view-filter.js [ Pass Failure ] crbug.com/v8/8381 http/tests/devtools/coverage/coverage-view.js [ Pass Failure ] crbug.com/v8/8381 http/tests/devtools/coverage/multiple-instances-merge.js [ Pass Failure ] +# Sheriff 2018-12-20 +crbug.com/916899 [ Win10 ] virtual/stable/webexposed/global-interface-listing-platform-specific.html [ Failure ] + # TODO (michaelludwig): Todo after Skia roll and rebaseline crbug.com/915735 compositing/masks/mask-with-added-filters.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 616adc7..5582f04e 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -50,6 +50,11 @@ "args": ["--enable-threaded-compositing"] }, { + "prefix": "threaded", + "base": "external/wpt/requestidlecallback", + "args": ["--enable-threaded-compositing"] + }, + { "prefix": "prefer_compositing_to_lcd_text", "base": "compositing/overflow", "args": ["--enable-prefer-compositing-to-lcd-text"] @@ -1019,5 +1024,10 @@ "prefix": "spatial-navigation-force-outline", "base": "fast/spatial-navigation", "args": ["--enable-blink-features=SpatialNavigationForcesOutline"] + }, + { + "prefix": "bidi-caret-affinity", + "base": "editing", + "args": ["--enable-blink-features=BidiCaretAffinity"] } ]
diff --git a/third_party/blink/web_tests/badging/badge-error.html b/third_party/blink/web_tests/badging/badge-error.html index 783528f..24e6a1b0a 100644 --- a/third_party/blink/web_tests/badging/badge-error.html +++ b/third_party/blink/web_tests/badging/badge-error.html
@@ -11,11 +11,9 @@ <body> <script> -badge_test(() => { Badge.set(-1); }, 'setBadge', 'TypeError'); +badge_test(() => { Badge.set(-1); }, 'setInteger', 'TypeError'); -badge_test(() => { Badge.set(0); }, 'setBadge', 'TypeError'); - -badge_test(() => { Badge.set(""); }, 'setBadge', 'TypeError'); +badge_test(() => { Badge.set("Foo"); }, 'setInteger', 'TypeError'); </script> </body>
diff --git a/third_party/blink/web_tests/badging/badge-success.html b/third_party/blink/web_tests/badging/badge-success.html index 47a1e50..619c3e2 100644 --- a/third_party/blink/web_tests/badging/badge-success.html +++ b/third_party/blink/web_tests/badging/badge-success.html
@@ -11,15 +11,14 @@ <body> <script> -badge_test(() => { Badge.set(); }, 'setBadge'); +badge_test(() => { Badge.set(); }, 'setFlag'); -badge_test(() => { Badge.set(undefined); }, 'setBadge'); +badge_test(() => { Badge.set(undefined); }, 'setFlag'); -badge_test(() => { Badge.set(null); }, 'setBadge'); +badge_test(() => { Badge.set(1); }, 'setInteger'); -badge_test(() => { Badge.set(1); }, 'setBadge'); - -badge_test(() => { Badge.set("a string"); }, 'setBadge'); +// Setting the Badge to 0 should be equivalent to clearing the badge. +badge_test(() => { Badge.set(0); }, 'clearBadge'); badge_test(() => { Badge.clear(); }, 'clearBadge');
diff --git a/third_party/blink/web_tests/badging/idl.html b/third_party/blink/web_tests/badging/idl.html index e0834c9..825f92f 100644 --- a/third_party/blink/web_tests/badging/idl.html +++ b/third_party/blink/web_tests/badging/idl.html
@@ -7,7 +7,7 @@ <script type="text/plain" id="tested"> interface Badge { [CallWith=ScriptState, RaisesException] - static void set(optional (USVString or long) contents); + static void set(optional long contents); [CallWith=ScriptState] static void clear(); }; </script>
diff --git a/third_party/blink/web_tests/badging/resources/mock-badge-service.js b/third_party/blink/web_tests/badging/resources/mock-badge-service.js index e836ed2..b9a9fc8 100644 --- a/third_party/blink/web_tests/badging/resources/mock-badge-service.js +++ b/third_party/blink/web_tests/badging/resources/mock-badge-service.js
@@ -18,16 +18,24 @@ }); } - setBadge(contents) { + setInteger(contents) { try { - assert_equals(this.expectCalled_, 'setBadge'); - assert_equals(contents, undefined); + assert_equals(this.expectCalled_, 'setInteger'); this.resolve_(); } catch (error) { this.reject_(error); } } + setFlag() { + try { + assert_equals(this.expectCalled_, 'setFlag'); + this.resolve_(); + } catch (error) { + this.reject(error); + } + } + clearBadge() { try { assert_equals(this.expectCalled_, 'clearBadge');
diff --git a/third_party/blink/web_tests/bluetooth/requestLEScan/basic-scan.https.html b/third_party/blink/web_tests/bluetooth/requestLEScan/basic-scan.https.html new file mode 100644 index 0000000..31669be --- /dev/null +++ b/third_party/blink/web_tests/bluetooth/requestLEScan/basic-scan.https.html
@@ -0,0 +1,32 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../../resources/testdriver.js"></script> +<script src="../../resources/testdriver-vendor.js"></script> +<script src="../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> +<script src="../../external/wpt/bluetooth/resources/bluetooth-scanning-helpers.js"></script> +<script> +'use strict'; +const test_desc = 'requestLEScan receive a scan result.'; + +bluetooth_test(async (t) => { + const fake_central = + await navigator.bluetooth.test.simulateCentral({state: 'powered-on'}); + + await callWithTrustedClick(async () => { + let scan = await navigator.bluetooth.requestLEScan(); + assert_equals(scan.constructor.name, 'BluetoothLEScan'); + }); + + const eventWatcher = new EventWatcher(t, + navigator.bluetooth, ['advertisementreceived']); + + let promise = eventWatcher.wait_for('advertisementreceived').then(e => { + verifyBluetoothAdvertisingEvent(e); + }); + fake_central.simulateAdvertisementReceived(scanResult); + return promise; + +}, test_desc); + +</script>
diff --git a/third_party/blink/web_tests/bluetooth/requestLEScan/doesnt-consume-user-gesture.https.html b/third_party/blink/web_tests/bluetooth/requestLEScan/doesnt-consume-user-gesture.https.html new file mode 100644 index 0000000..803ddc3 --- /dev/null +++ b/third_party/blink/web_tests/bluetooth/requestLEScan/doesnt-consume-user-gesture.https.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../../resources/testdriver.js"></script> +<script src="../../resources/testdriver-vendor.js"></script> +<script src="../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> +<script> +'use strict'; +const test_desc = 'requestLEScan calls do not consume user gestures.'; + +bluetooth_test(() => navigator.bluetooth.test.simulateCentral({ state: 'powered-on' }) + .then(() => callWithTrustedClick(() => { + let first = navigator.bluetooth.requestLEScan(); + let second = navigator.bluetooth.requestLEScan(); + return Promise.all([ + first.then(scan => assert_equals( + scan.constructor.name, 'BluetoothLEScan')), + second.then(scan => assert_equals( + scan.constructor.name, 'BluetoothLEScan')), + ]); + })), test_desc); +</script>
diff --git a/third_party/blink/web_tests/bluetooth/requestLEScan/le-not-supported.https.html b/third_party/blink/web_tests/bluetooth/requestLEScan/le-not-supported.https.html new file mode 100644 index 0000000..8b8079a5 --- /dev/null +++ b/third_party/blink/web_tests/bluetooth/requestLEScan/le-not-supported.https.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../../resources/testdriver.js"></script> +<script src="../../resources/testdriver-vendor.js"></script> +<script src="../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> +<script> +'use strict'; +const test_desc = 'requestLEScan reject with NotFoundError if Bluetooth is not supported.'; +const expected = new DOMException('Bluetooth Low Energy not available.', + 'NotFoundError'); + +bluetooth_test(() => navigator.bluetooth.test.setLESupported(false) + .then(() => assert_promise_rejects_with_message( + requestLEScanWithTrustedClick(), + expected, 'Bluetooth Low Energy is not supported.')), + test_desc); +</script>
diff --git a/third_party/blink/web_tests/bluetooth/requestLEScan/multiple-scan.https.html b/third_party/blink/web_tests/bluetooth/requestLEScan/multiple-scan.https.html new file mode 100644 index 0000000..8291428 --- /dev/null +++ b/third_party/blink/web_tests/bluetooth/requestLEScan/multiple-scan.https.html
@@ -0,0 +1,38 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../../resources/testdriver.js"></script> +<script src="../../resources/testdriver-vendor.js"></script> +<script src="../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> +<script src="../../external/wpt/bluetooth/resources/bluetooth-scanning-helpers.js"></script> +<script> +'use strict'; +const test_desc = 'Multiple requestLEScan receive a scan result.'; + +let scan; +let scan2; + +bluetooth_test(async (t) => { + const fake_central = + await navigator.bluetooth.test.simulateCentral({state: 'powered-on'}); + + await callWithTrustedClick(async () => { + scan = await navigator.bluetooth.requestLEScan(); + scan2 = await navigator.bluetooth.requestLEScan(); + }); + + scan2.stop() + + // We should still get an event because we called requestLEScan twice. + const eventWatcher = new EventWatcher(t, + navigator.bluetooth, ['advertisementreceived']); + + let promise = eventWatcher.wait_for('advertisementreceived').then(e => { + verifyBluetoothAdvertisingEvent(e); + }); + fake_central.simulateAdvertisementReceived(scanResult); + return promise; + +}, test_desc); + +</script>
diff --git a/third_party/blink/web_tests/bluetooth/requestLEScan/radio-not-present.https.html b/third_party/blink/web_tests/bluetooth/requestLEScan/radio-not-present.https.html new file mode 100644 index 0000000..d6ac9e3 --- /dev/null +++ b/third_party/blink/web_tests/bluetooth/requestLEScan/radio-not-present.https.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../../resources/testdriver.js"></script> +<script src="../../resources/testdriver-vendor.js"></script> +<script src="../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> +<script> +'use strict'; +const test_desc = 'requestLEScan reject with NotFoundError if there is no BT radio present.'; +const expected = new DOMException('Bluetooth adapter not available.', + 'NotFoundError'); + +bluetooth_test(() => navigator.bluetooth.test.simulateCentral({state: 'absent'}) + .then(() => assert_promise_rejects_with_message( + requestLEScanWithTrustedClick(), + expected, 'Bluetooth adapter is not present.')), + test_desc); +</script>
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json index 927f604..dc84a50 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -3871,6 +3871,12 @@ {} ] ], + "feature-policy/experimental-features/vertical-scroll-main-frame-manual.tentative.html": [ + [ + "/feature-policy/experimental-features/vertical-scroll-main-frame-manual.tentative.html", + {} + ] + ], "feature-policy/experimental-features/vertical-scroll-touch-action-manual.tentative.html": [ [ "/feature-policy/experimental-features/vertical-scroll-touch-action-manual.tentative.html", @@ -89803,6 +89809,18 @@ {} ] ], + "css/filter-effects/filter-subregion-01.html": [ + [ + "/css/filter-effects/filter-subregion-01.html", + [ + [ + "/css/filter-effects/filter-subregion-01-ref.html", + "==" + ] + ], + {} + ] + ], "css/filter-effects/filtered-block-is-container.html": [ [ "/css/filter-effects/filtered-block-is-container.html", @@ -113586,6 +113604,11 @@ {} ] ], + "bluetooth/resources/bluetooth-scanning-helpers.js": [ + [ + {} + ] + ], "bluetooth/resources/health-thermometer-iframe.html": [ [ {} @@ -135186,6 +135209,11 @@ {} ] ], + "css/css-grid/parsing/grid-area-computed-expected.txt": [ + [ + {} + ] + ], "css/css-grid/reference/display-grid-ref.html": [ [ {} @@ -149046,6 +149074,11 @@ {} ] ], + "css/filter-effects/filter-subregion-01-ref.html": [ + [ + {} + ] + ], "css/filter-effects/filtered-block-is-container-ref.html": [ [ {} @@ -149206,6 +149239,11 @@ {} ] ], + "css/filter-effects/support/filtersubregion00.png": [ + [ + {} + ] + ], "css/filter-effects/support/import-green.css": [ [ {} @@ -155621,6 +155659,11 @@ {} ] ], + "feature-policy/experimental-features/vertical-scroll-main-frame-manual.tentative.html.headers": [ + [ + {} + ] + ], "feature-policy/feature-policy-frame-policy-allowed-for-all.https.sub.html.sub.headers": [ [ {} @@ -169716,6 +169759,11 @@ {} ] ], + "infrastructure/metadata/infrastructure/testdriver/actions/elementTiming.html.ini": [ + [ + {} + ] + ], "infrastructure/metadata/infrastructure/testdriver/actions/eventOrder.html.ini": [ [ {} @@ -173516,6 +173564,11 @@ {} ] ], + "portals/resources/postmessage-referrer.sub.html": [ + [ + {} + ] + ], "preload/META.yml": [ [ {} @@ -180916,6 +180969,26 @@ {} ] ], + "signed-exchange/resources/sxg-inner-url-bom.sxg": [ + [ + {} + ] + ], + "signed-exchange/resources/sxg-inner-url-bom.sxg.headers": [ + [ + {} + ] + ], + "signed-exchange/resources/sxg-invalid-utf8-inner-url.sxg": [ + [ + {} + ] + ], + "signed-exchange/resources/sxg-invalid-utf8-inner-url.sxg.headers": [ + [ + {} + ] + ], "signed-exchange/resources/sxg-invalid-validity-url.sxg": [ [ {} @@ -180941,6 +181014,16 @@ {} ] ], + "signed-exchange/resources/sxg-utf8-inner-url.sxg": [ + [ + {} + ] + ], + "signed-exchange/resources/sxg-utf8-inner-url.sxg.headers": [ + [ + {} + ] + ], "signed-exchange/resources/sxg-util.js": [ [ {} @@ -206875,6 +206958,12 @@ {} ] ], + "css/css-grid/parsing/grid-area-computed.html": [ + [ + "/css/css-grid/parsing/grid-area-computed.html", + {} + ] + ], "css/css-grid/parsing/grid-area-invalid.html": [ [ "/css/css-grid/parsing/grid-area-invalid.html", @@ -206887,6 +206976,12 @@ {} ] ], + "css/css-grid/parsing/grid-auto-columns-computed.html": [ + [ + "/css/css-grid/parsing/grid-auto-columns-computed.html", + {} + ] + ], "css/css-grid/parsing/grid-auto-columns-invalid.html": [ [ "/css/css-grid/parsing/grid-auto-columns-invalid.html", @@ -206899,6 +206994,12 @@ {} ] ], + "css/css-grid/parsing/grid-auto-flow-computed.html": [ + [ + "/css/css-grid/parsing/grid-auto-flow-computed.html", + {} + ] + ], "css/css-grid/parsing/grid-auto-flow-invalid.html": [ [ "/css/css-grid/parsing/grid-auto-flow-invalid.html", @@ -206911,6 +207012,12 @@ {} ] ], + "css/css-grid/parsing/grid-auto-rows-computed.html": [ + [ + "/css/css-grid/parsing/grid-auto-rows-computed.html", + {} + ] + ], "css/css-grid/parsing/grid-auto-rows-invalid.html": [ [ "/css/css-grid/parsing/grid-auto-rows-invalid.html", @@ -206923,6 +207030,12 @@ {} ] ], + "css/css-grid/parsing/grid-template-areas-computed.html": [ + [ + "/css/css-grid/parsing/grid-template-areas-computed.html", + {} + ] + ], "css/css-grid/parsing/grid-template-areas-invalid.html": [ [ "/css/css-grid/parsing/grid-template-areas-invalid.html", @@ -206935,6 +207048,12 @@ {} ] ], + "css/css-grid/placement/grid-auto-placement-implicit-tracks-001.html": [ + [ + "/css/css-grid/placement/grid-auto-placement-implicit-tracks-001.html", + {} + ] + ], "css/css-images/gradient/color-stops-parsing.html": [ [ "/css/css-images/gradient/color-stops-parsing.html", @@ -207175,6 +207294,84 @@ {} ] ], + "css/css-logical/parsing/block-size-invalid.html": [ + [ + "/css/css-logical/parsing/block-size-invalid.html", + {} + ] + ], + "css/css-logical/parsing/block-size-valid.html": [ + [ + "/css/css-logical/parsing/block-size-valid.html", + {} + ] + ], + "css/css-logical/parsing/inline-size-invalid.html": [ + [ + "/css/css-logical/parsing/inline-size-invalid.html", + {} + ] + ], + "css/css-logical/parsing/inline-size-valid.html": [ + [ + "/css/css-logical/parsing/inline-size-valid.html", + {} + ] + ], + "css/css-logical/parsing/max-block-size-invalid.html": [ + [ + "/css/css-logical/parsing/max-block-size-invalid.html", + {} + ] + ], + "css/css-logical/parsing/max-block-size-valid.html": [ + [ + "/css/css-logical/parsing/max-block-size-valid.html", + {} + ] + ], + "css/css-logical/parsing/max-inline-size-invalid.html": [ + [ + "/css/css-logical/parsing/max-inline-size-invalid.html", + {} + ] + ], + "css/css-logical/parsing/max-inline-size-valid.html": [ + [ + "/css/css-logical/parsing/max-inline-size-valid.html", + {} + ] + ], + "css/css-logical/parsing/min-block-size-invalid.html": [ + [ + "/css/css-logical/parsing/min-block-size-invalid.html", + {} + ] + ], + "css/css-logical/parsing/min-block-size-valid.html": [ + [ + "/css/css-logical/parsing/min-block-size-valid.html", + {} + ] + ], + "css/css-logical/parsing/min-inline-size-invalid.html": [ + [ + "/css/css-logical/parsing/min-inline-size-invalid.html", + {} + ] + ], + "css/css-logical/parsing/min-inline-size-valid.html": [ + [ + "/css/css-logical/parsing/min-inline-size-valid.html", + {} + ] + ], + "css/css-masking/clip-path/interpolation.html": [ + [ + "/css/css-masking/clip-path/interpolation.html", + {} + ] + ], "css/css-masking/idlharness.html": [ [ "/css/css-masking/idlharness.html", @@ -207283,6 +207480,12 @@ {} ] ], + "css/css-multicol/multicol-span-all-under-clip-path-crash.html": [ + [ + "/css/css-multicol/multicol-span-all-under-clip-path-crash.html", + {} + ] + ], "css/css-multicol/parsing/column-count-computed.html": [ [ "/css/css-multicol/parsing/column-count-computed.html", @@ -208309,6 +208512,12 @@ {} ] ], + "css/css-shapes/basic-shape-interpolation.html": [ + [ + "/css/css-shapes/basic-shape-interpolation.html", + {} + ] + ], "css/css-shapes/inheritance.html": [ [ "/css/css-shapes/inheritance.html", @@ -210667,12 +210876,24 @@ {} ] ], + "css/css-transforms/transform-origin-014.html": [ + [ + "/css/css-transforms/transform-origin-014.html", + {} + ] + ], "css/css-transforms/transform-origin-in-shadow.html": [ [ "/css/css-transforms/transform-origin-in-shadow.html", {} ] ], + "css/css-transforms/transform-percent-009.html": [ + [ + "/css/css-transforms/transform-percent-009.html", + {} + ] + ], "css/css-transforms/transform_translate.html": [ [ "/css/css-transforms/transform_translate.html", @@ -258667,6 +258888,12 @@ {} ] ], + "portals/portals-no-referrer.html": [ + [ + "/portals/portals-no-referrer.html", + {} + ] + ], "preload/avoid-delaying-onload-link-preload.html": [ [ "/preload/avoid-delaying-onload-link-preload.html", @@ -272139,6 +272366,18 @@ {} ] ], + "signed-exchange/sxg-inner-url-bom.tentative.html": [ + [ + "/signed-exchange/sxg-inner-url-bom.tentative.html", + {} + ] + ], + "signed-exchange/sxg-invalid-utf8-inner-url.tentative.html": [ + [ + "/signed-exchange/sxg-invalid-utf8-inner-url.tentative.html", + {} + ] + ], "signed-exchange/sxg-invalid-validity-url.tentative.html": [ [ "/signed-exchange/sxg-invalid-validity-url.tentative.html", @@ -272169,6 +272408,12 @@ {} ] ], + "signed-exchange/sxg-utf8-inner-url.tentative.html": [ + [ + "/signed-exchange/sxg-utf8-inner-url.tentative.html", + {} + ] + ], "speech-api/SpeechRecognition-basics.https.html": [ [ "/speech-api/SpeechRecognition-basics.https.html", @@ -272373,6 +272618,12 @@ {} ], [ + "/streams/byte-length-queuing-strategy.any.js", + { + "jsshell": true + } + ], + [ "/streams/byte-length-queuing-strategy.any.serviceworker.html", {} ], @@ -272391,6 +272642,12 @@ {} ], [ + "/streams/count-queuing-strategy.any.js", + { + "jsshell": true + } + ], + [ "/streams/count-queuing-strategy.any.serviceworker.html", {} ], @@ -272409,6 +272666,12 @@ {} ], [ + "/streams/piping/abort.any.js", + { + "jsshell": true + } + ], + [ "/streams/piping/abort.any.serviceworker.html", {} ], @@ -272427,6 +272690,12 @@ {} ], [ + "/streams/piping/close-propagation-backward.any.js", + { + "jsshell": true + } + ], + [ "/streams/piping/close-propagation-backward.any.serviceworker.html", {} ], @@ -272445,6 +272714,12 @@ {} ], [ + "/streams/piping/close-propagation-forward.any.js", + { + "jsshell": true + } + ], + [ "/streams/piping/close-propagation-forward.any.serviceworker.html", {} ], @@ -272463,6 +272738,12 @@ {} ], [ + "/streams/piping/error-propagation-backward.any.js", + { + "jsshell": true + } + ], + [ "/streams/piping/error-propagation-backward.any.serviceworker.html", {} ], @@ -272481,6 +272762,12 @@ {} ], [ + "/streams/piping/error-propagation-forward.any.js", + { + "jsshell": true + } + ], + [ "/streams/piping/error-propagation-forward.any.serviceworker.html", {} ], @@ -272499,6 +272786,12 @@ {} ], [ + "/streams/piping/flow-control.any.js", + { + "jsshell": true + } + ], + [ "/streams/piping/flow-control.any.serviceworker.html", {} ], @@ -272517,6 +272810,12 @@ {} ], [ + "/streams/piping/general.any.js", + { + "jsshell": true + } + ], + [ "/streams/piping/general.any.serviceworker.html", {} ], @@ -272535,6 +272834,12 @@ {} ], [ + "/streams/piping/multiple-propagation.any.js", + { + "jsshell": true + } + ], + [ "/streams/piping/multiple-propagation.any.serviceworker.html", {} ], @@ -272553,6 +272858,12 @@ {} ], [ + "/streams/piping/pipe-through.any.js", + { + "jsshell": true + } + ], + [ "/streams/piping/pipe-through.any.serviceworker.html", {} ], @@ -272571,6 +272882,12 @@ {} ], [ + "/streams/piping/then-interception.any.js", + { + "jsshell": true + } + ], + [ "/streams/piping/then-interception.any.serviceworker.html", {} ], @@ -272589,6 +272906,12 @@ {} ], [ + "/streams/piping/transform-streams.any.js", + { + "jsshell": true + } + ], + [ "/streams/piping/transform-streams.any.serviceworker.html", {} ], @@ -272607,6 +272930,12 @@ {} ], [ + "/streams/readable-byte-streams/brand-checks.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-byte-streams/brand-checks.any.serviceworker.html", {} ], @@ -272625,6 +272954,12 @@ {} ], [ + "/streams/readable-byte-streams/construct-byob-request.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-byte-streams/construct-byob-request.any.serviceworker.html", {} ], @@ -272643,6 +272978,12 @@ {} ], [ + "/streams/readable-byte-streams/constructor.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-byte-streams/constructor.any.serviceworker.html", {} ], @@ -272661,6 +273002,12 @@ {} ], [ + "/streams/readable-byte-streams/detached-buffers.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-byte-streams/detached-buffers.any.serviceworker.html", {} ], @@ -272679,6 +273026,12 @@ {} ], [ + "/streams/readable-byte-streams/general.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-byte-streams/general.any.serviceworker.html", {} ], @@ -272697,6 +273050,12 @@ {} ], [ + "/streams/readable-byte-streams/properties.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-byte-streams/properties.any.serviceworker.html", {} ], @@ -272715,6 +273074,12 @@ {} ], [ + "/streams/readable-streams/bad-strategies.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-streams/bad-strategies.any.serviceworker.html", {} ], @@ -272733,6 +273098,12 @@ {} ], [ + "/streams/readable-streams/bad-underlying-sources.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-streams/bad-underlying-sources.any.serviceworker.html", {} ], @@ -272751,6 +273122,12 @@ {} ], [ + "/streams/readable-streams/brand-checks.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-streams/brand-checks.any.serviceworker.html", {} ], @@ -272769,6 +273146,12 @@ {} ], [ + "/streams/readable-streams/cancel.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-streams/cancel.any.serviceworker.html", {} ], @@ -272787,6 +273170,12 @@ {} ], [ + "/streams/readable-streams/constructor.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-streams/constructor.any.serviceworker.html", {} ], @@ -272805,6 +273194,12 @@ {} ], [ + "/streams/readable-streams/count-queuing-strategy-integration.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-streams/count-queuing-strategy-integration.any.serviceworker.html", {} ], @@ -272823,6 +273218,12 @@ {} ], [ + "/streams/readable-streams/default-reader.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-streams/default-reader.any.serviceworker.html", {} ], @@ -272841,6 +273242,12 @@ {} ], [ + "/streams/readable-streams/floating-point-total-queue-size.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-streams/floating-point-total-queue-size.any.serviceworker.html", {} ], @@ -272859,6 +273266,12 @@ {} ], [ + "/streams/readable-streams/garbage-collection.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-streams/garbage-collection.any.serviceworker.html", {} ], @@ -272877,6 +273290,12 @@ {} ], [ + "/streams/readable-streams/general.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-streams/general.any.serviceworker.html", {} ], @@ -272895,6 +273314,12 @@ {} ], [ + "/streams/readable-streams/patched-global.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-streams/patched-global.any.serviceworker.html", {} ], @@ -272913,6 +273338,12 @@ {} ], [ + "/streams/readable-streams/reentrant-strategies.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-streams/reentrant-strategies.any.serviceworker.html", {} ], @@ -272931,6 +273362,12 @@ {} ], [ + "/streams/readable-streams/tee.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-streams/tee.any.serviceworker.html", {} ], @@ -272949,6 +273386,12 @@ {} ], [ + "/streams/readable-streams/templated.any.js", + { + "jsshell": true + } + ], + [ "/streams/readable-streams/templated.any.serviceworker.html", {} ], @@ -272967,6 +273410,12 @@ {} ], [ + "/streams/transform-streams/backpressure.any.js", + { + "jsshell": true + } + ], + [ "/streams/transform-streams/backpressure.any.serviceworker.html", {} ], @@ -272985,6 +273434,12 @@ {} ], [ + "/streams/transform-streams/brand-checks.any.js", + { + "jsshell": true + } + ], + [ "/streams/transform-streams/brand-checks.any.serviceworker.html", {} ], @@ -273003,6 +273458,12 @@ {} ], [ + "/streams/transform-streams/constructor.any.js", + { + "jsshell": true + } + ], + [ "/streams/transform-streams/constructor.any.serviceworker.html", {} ], @@ -273021,6 +273482,12 @@ {} ], [ + "/streams/transform-streams/errors.any.js", + { + "jsshell": true + } + ], + [ "/streams/transform-streams/errors.any.serviceworker.html", {} ], @@ -273039,6 +273506,12 @@ {} ], [ + "/streams/transform-streams/flush.any.js", + { + "jsshell": true + } + ], + [ "/streams/transform-streams/flush.any.serviceworker.html", {} ], @@ -273057,6 +273530,12 @@ {} ], [ + "/streams/transform-streams/general.any.js", + { + "jsshell": true + } + ], + [ "/streams/transform-streams/general.any.serviceworker.html", {} ], @@ -273075,6 +273554,12 @@ {} ], [ + "/streams/transform-streams/lipfuzz.any.js", + { + "jsshell": true + } + ], + [ "/streams/transform-streams/lipfuzz.any.serviceworker.html", {} ], @@ -273093,6 +273578,12 @@ {} ], [ + "/streams/transform-streams/patched-global.any.js", + { + "jsshell": true + } + ], + [ "/streams/transform-streams/patched-global.any.serviceworker.html", {} ], @@ -273111,6 +273602,12 @@ {} ], [ + "/streams/transform-streams/properties.any.js", + { + "jsshell": true + } + ], + [ "/streams/transform-streams/properties.any.serviceworker.html", {} ], @@ -273129,6 +273626,12 @@ {} ], [ + "/streams/transform-streams/reentrant-strategies.any.js", + { + "jsshell": true + } + ], + [ "/streams/transform-streams/reentrant-strategies.any.serviceworker.html", {} ], @@ -273147,6 +273650,12 @@ {} ], [ + "/streams/transform-streams/strategies.any.js", + { + "jsshell": true + } + ], + [ "/streams/transform-streams/strategies.any.serviceworker.html", {} ], @@ -273165,6 +273674,12 @@ {} ], [ + "/streams/transform-streams/terminate.any.js", + { + "jsshell": true + } + ], + [ "/streams/transform-streams/terminate.any.serviceworker.html", {} ], @@ -273183,6 +273698,12 @@ {} ], [ + "/streams/writable-streams/aborting.any.js", + { + "jsshell": true + } + ], + [ "/streams/writable-streams/aborting.any.serviceworker.html", {} ], @@ -273201,6 +273722,12 @@ {} ], [ + "/streams/writable-streams/bad-strategies.any.js", + { + "jsshell": true + } + ], + [ "/streams/writable-streams/bad-strategies.any.serviceworker.html", {} ], @@ -273219,6 +273746,12 @@ {} ], [ + "/streams/writable-streams/bad-underlying-sinks.any.js", + { + "jsshell": true + } + ], + [ "/streams/writable-streams/bad-underlying-sinks.any.serviceworker.html", {} ], @@ -273237,6 +273770,12 @@ {} ], [ + "/streams/writable-streams/brand-checks.any.js", + { + "jsshell": true + } + ], + [ "/streams/writable-streams/brand-checks.any.serviceworker.html", {} ], @@ -273255,6 +273794,12 @@ {} ], [ + "/streams/writable-streams/byte-length-queuing-strategy.any.js", + { + "jsshell": true + } + ], + [ "/streams/writable-streams/byte-length-queuing-strategy.any.serviceworker.html", {} ], @@ -273273,6 +273818,12 @@ {} ], [ + "/streams/writable-streams/close.any.js", + { + "jsshell": true + } + ], + [ "/streams/writable-streams/close.any.serviceworker.html", {} ], @@ -273291,6 +273842,12 @@ {} ], [ + "/streams/writable-streams/constructor.any.js", + { + "jsshell": true + } + ], + [ "/streams/writable-streams/constructor.any.serviceworker.html", {} ], @@ -273309,6 +273866,12 @@ {} ], [ + "/streams/writable-streams/count-queuing-strategy.any.js", + { + "jsshell": true + } + ], + [ "/streams/writable-streams/count-queuing-strategy.any.serviceworker.html", {} ], @@ -273327,6 +273890,12 @@ {} ], [ + "/streams/writable-streams/error.any.js", + { + "jsshell": true + } + ], + [ "/streams/writable-streams/error.any.serviceworker.html", {} ], @@ -273345,6 +273914,12 @@ {} ], [ + "/streams/writable-streams/floating-point-total-queue-size.any.js", + { + "jsshell": true + } + ], + [ "/streams/writable-streams/floating-point-total-queue-size.any.serviceworker.html", {} ], @@ -273363,6 +273938,12 @@ {} ], [ + "/streams/writable-streams/general.any.js", + { + "jsshell": true + } + ], + [ "/streams/writable-streams/general.any.serviceworker.html", {} ], @@ -273381,6 +273962,12 @@ {} ], [ + "/streams/writable-streams/properties.any.js", + { + "jsshell": true + } + ], + [ "/streams/writable-streams/properties.any.serviceworker.html", {} ], @@ -273399,6 +273986,12 @@ {} ], [ + "/streams/writable-streams/reentrant-strategy.any.js", + { + "jsshell": true + } + ], + [ "/streams/writable-streams/reentrant-strategy.any.serviceworker.html", {} ], @@ -273417,6 +274010,12 @@ {} ], [ + "/streams/writable-streams/start.any.js", + { + "jsshell": true + } + ], + [ "/streams/writable-streams/start.any.serviceworker.html", {} ], @@ -273435,6 +274034,12 @@ {} ], [ + "/streams/writable-streams/write.any.js", + { + "jsshell": true + } + ], + [ "/streams/writable-streams/write.any.serviceworker.html", {} ], @@ -273603,6 +274208,12 @@ {} ] ], + "svg/geometry/parsing/sizing-properties-computed.svg": [ + [ + "/svg/geometry/parsing/sizing-properties-computed.svg", + {} + ] + ], "svg/geometry/parsing/width-computed.svg": [ [ "/svg/geometry/parsing/width-computed.svg", @@ -279431,6 +280042,12 @@ {} ] ], + "webrtc/RTCTrackEvent-fire.html": [ + [ + "/webrtc/RTCTrackEvent-fire.html", + {} + ] + ], "webrtc/datachannel-emptystring.html": [ [ "/webrtc/datachannel-emptystring.html", @@ -300571,11 +301188,11 @@ "testharness" ], "background-fetch/fetch.https.window-expected.txt": [ - "c603f0383a33c7c74033ceef203e9dc24a82f147", + "6b5660569bf333166981d4fcca0f53a8a2b83045", "support" ], "background-fetch/fetch.https.window.js": [ - "6a8cf6c0e3a98d33c20ea3b9f3f8c2a274803998", + "a806414e46f8a772088840c1b0fd5101f4970350", "testharness" ], "background-fetch/get-ids.https.window.js": [ @@ -301031,7 +301648,7 @@ "testharness" ], "bluetooth/idl/idlharness.tentative.https.window-expected.txt": [ - "e5d18e75caf74f49ee2f1ad67ca2dc18f627be24", + "6c2db97b148401f781ec99bb383b475a459450e9", "support" ], "bluetooth/idl/idlharness.tentative.https.window.js": [ @@ -301187,7 +301804,11 @@ "testharness" ], "bluetooth/resources/bluetooth-helpers.js": [ - "c4e26077c34283cc6d442cc8bc57f799eadd5a99", + "64a20c2f994164abd16d77143b5e39da89927ed4", + "support" + ], + "bluetooth/resources/bluetooth-scanning-helpers.js": [ + "9b173e6367ce2173336299e4ea005668ca53a03f", "support" ], "bluetooth/resources/health-thermometer-iframe.html": [ @@ -342018,6 +342639,14 @@ "ef6c78f99a950e90fbb32871c221aea453c593a0", "support" ], + "css/css-grid/parsing/grid-area-computed-expected.txt": [ + "a56967d780ee890fee7899bc4ae688ae090c6fa1", + "support" + ], + "css/css-grid/parsing/grid-area-computed.html": [ + "731b7ebda61e5bfe7f3bdde12beef6b69e786398", + "testharness" + ], "css/css-grid/parsing/grid-area-invalid.html": [ "b989322775eb7dbf273a3dc3fbb3d1af31f524ba", "testharness" @@ -342026,6 +342655,10 @@ "8e7d0d43d1cfac44935593892b67fdb40b179791", "testharness" ], + "css/css-grid/parsing/grid-auto-columns-computed.html": [ + "6aea96a80f6dcf2416f19b854293f23fa05d7854", + "testharness" + ], "css/css-grid/parsing/grid-auto-columns-invalid.html": [ "e7a965f34ad35f32589b6fc895d65946812e0749", "testharness" @@ -342034,6 +342667,10 @@ "ba1f5f60d657ebd2629c94b90c971bb081ea7917", "testharness" ], + "css/css-grid/parsing/grid-auto-flow-computed.html": [ + "7484f62ddb6ea6b878245c3567f62fc908428f8c", + "testharness" + ], "css/css-grid/parsing/grid-auto-flow-invalid.html": [ "a261e8eba11fd295eb33c9288a7e30f589374331", "testharness" @@ -342042,6 +342679,10 @@ "4270a3df933f372792139cae7c39344ff69482dc", "testharness" ], + "css/css-grid/parsing/grid-auto-rows-computed.html": [ + "071c16928e57197c6bba9dcb25597bfebe13d5e7", + "testharness" + ], "css/css-grid/parsing/grid-auto-rows-invalid.html": [ "7fceaa0f1639494847cc06a7f93876992d620b3c", "testharness" @@ -342050,6 +342691,10 @@ "cf63e2b7d52a6fffc5577bc55e37dfd6aa0cd5b8", "testharness" ], + "css/css-grid/parsing/grid-template-areas-computed.html": [ + "84627f8d2851ee234276016a89dea6a42eb3b202", + "testharness" + ], "css/css-grid/parsing/grid-template-areas-invalid.html": [ "5bc70c5697a2a642ce80b902851f3687eba901d7", "testharness" @@ -342058,6 +342703,10 @@ "9c9bd47ec894ccc0e389287120082fb4bf5c9905", "testharness" ], + "css/css-grid/placement/grid-auto-placement-implicit-tracks-001.html": [ + "546336a6ce8208d7c30afd66e20fbe33040cbd7c", + "testharness" + ], "css/css-grid/placement/grid-layout-grid-span.html": [ "21aad99708c96942c196ada03beaded1d73a1078", "reftest" @@ -343334,6 +343983,54 @@ "3e133db880cd32d963d701bb184d28faae959aa5", "testharness" ], + "css/css-logical/parsing/block-size-invalid.html": [ + "37d88907735ff58ab4bebb9073f626e14d864955", + "testharness" + ], + "css/css-logical/parsing/block-size-valid.html": [ + "47170e48f15f90488542daf7ede743cd55f75172", + "testharness" + ], + "css/css-logical/parsing/inline-size-invalid.html": [ + "d3d5d3f84d9d01392533e787b9e6755d592ec96e", + "testharness" + ], + "css/css-logical/parsing/inline-size-valid.html": [ + "e785b468cdde191c811b57d74df59d5574314f91", + "testharness" + ], + "css/css-logical/parsing/max-block-size-invalid.html": [ + "adcf6e497eac2ecbf3e28c50074a3e6ed83b0af6", + "testharness" + ], + "css/css-logical/parsing/max-block-size-valid.html": [ + "75b5c6f54973ef162cfb67f775f68f9958ede259", + "testharness" + ], + "css/css-logical/parsing/max-inline-size-invalid.html": [ + "fa695551b2448b767e15b85979618f255d64e1c7", + "testharness" + ], + "css/css-logical/parsing/max-inline-size-valid.html": [ + "19d582962dc04f879bf56603d1afe73cb08eaef4", + "testharness" + ], + "css/css-logical/parsing/min-block-size-invalid.html": [ + "325dc2e0aeac61845ead7684d2a8aa6fb9103c86", + "testharness" + ], + "css/css-logical/parsing/min-block-size-valid.html": [ + "5a5d4a43852d96105bd207dec9c9c8dbd5b6403d", + "testharness" + ], + "css/css-logical/parsing/min-inline-size-invalid.html": [ + "eb2cc8bb1067335ef6789c0fcece0a76df82f6c1", + "testharness" + ], + "css/css-logical/parsing/min-inline-size-valid.html": [ + "fa4ba0d1bb2607d954d3a2ea3272282872704799", + "testharness" + ], "css/css-logical/reference/logical-values-float-clear-reftest-ref.html": [ "28c275ebb307a3db20c019daebe140e3fa591971", "support" @@ -343994,6 +344691,10 @@ "8d2c049a7e758e496eb2f823b808fd971468b795", "reftest" ], + "css/css-masking/clip-path/interpolation.html": [ + "da3981feed6ed681ee4a7d88b7ecd167b9fd5c7b", + "testharness" + ], "css/css-masking/clip-path/reference/clip-path-circle-2-ref.html": [ "7794d32b3f0e2415dbfda8ff12475b0e4f0b4117", "support" @@ -345406,6 +346107,10 @@ "41ac007f00009d60c43b034bce68ded4cf23a007", "reftest" ], + "css/css-multicol/multicol-span-all-under-clip-path-crash.html": [ + "d37a120b2e0c43be637b0418002db45a53c4975b", + "testharness" + ], "css/css-multicol/multicol-span-float-001-ref.xht": [ "50addc37797b085d7c59e7389f99fca1c54c50c1", "support" @@ -347974,6 +348679,10 @@ "5e4842d234f6af393a5ee04fa604a63f6db5cae1", "testharness" ], + "css/css-shapes/basic-shape-interpolation.html": [ + "beea230697f0da8359447e6034835ba5766a9e24", + "testharness" + ], "css/css-shapes/inheritance.html": [ "490775dd8ce24721046f89234237d8f7c200623c", "testharness" @@ -358566,6 +359275,10 @@ "64f52df125f5d76023bb77036fc845c2c61d551f", "reftest" ], + "css/css-transforms/transform-origin-014.html": [ + "c350166430e649e502e17b53cf32ac498c6b8543", + "testharness" + ], "css/css-transforms/transform-origin-in-shadow.html": [ "ebbc616ff8eebb4de6c79bcc29e61227ba969476", "testharness" @@ -359022,6 +359735,10 @@ "bfede24f007033fb2e2dc224902de5d232bea9c8", "reftest" ], + "css/css-transforms/transform-percent-009.html": [ + "c6d64be3c36f003dc33eb479b9f268844edf3a76", + "testharness" + ], "css/css-transforms/transform-percent-notref.html": [ "96c70ec6d37318b6c6827edc74f6b9a3f7a6bb8f", "support" @@ -374278,6 +374995,14 @@ "d00c1ce8c4c606c088efc9322301f71a8d1ce0d5", "reftest" ], + "css/filter-effects/filter-subregion-01-ref.html": [ + "a91e1fa0d24f87812fcf41b914193df4f5e049be", + "support" + ], + "css/filter-effects/filter-subregion-01.html": [ + "08c8367f240dbe1ec76778d2e1cc318c73b00cc1", + "reftest" + ], "css/filter-effects/filtered-block-is-container-ref.html": [ "fc9467f8717dfc722dcb6dbbbb31bfd8c2baee3b", "support" @@ -374518,6 +375243,10 @@ "0d5fc65c6fdfe2b4f507326fb379e468dbe85d46", "support" ], + "css/filter-effects/support/filtersubregion00.png": [ + "b6c4bccb63cd850f473a59d9e3c0cf26c699db13", + "support" + ], "css/filter-effects/support/import-green.css": [ "537104e663364492c6ef388e4afce190e9c5bc58", "support" @@ -387642,6 +388371,14 @@ "6036234de18eedc0a52eb3129a2588e33b9bbcf3", "reftest" ], + "feature-policy/experimental-features/vertical-scroll-main-frame-manual.tentative.html": [ + "6392ea5bfb0ef0b65ca7917ef3053ee73c1f8254", + "manual" + ], + "feature-policy/experimental-features/vertical-scroll-main-frame-manual.tentative.html.headers": [ + "44072fce5640c79fcbd804550bfce44dbad37738", + "support" + ], "feature-policy/experimental-features/vertical-scroll-scrollintoview.tentative.html": [ "689685a4977a7ab08c5183fe04e427c25ce6f3cf", "testharness" @@ -387763,11 +388500,11 @@ "support" ], "feature-policy/idlharness.window-expected.txt": [ - "71a041e90710f0287c8b864a511e49caf1305ba3", + "43914ea6d4e64618dfe12c697829a428cc2c3a4e", "support" ], "feature-policy/idlharness.window.js": [ - "fb17cab982acecdb7d8aadcc02544bc7cae1a2bb", + "33bbe3c14ffe28d961cc4c71c0b367028ff8d2df", "testharness" ], "feature-policy/payment-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html": [ @@ -402903,7 +403640,7 @@ "support" ], "html/semantics/embedded-content/the-iframe-element/iframe_javascript_url_01.htm": [ - "d6c2abe7d57655261ca935a6d5d61bc8d7d5fe44", + "fd65f932982907bf62ab6455c9ab94612b0dca7a", "testharness" ], "html/semantics/embedded-content/the-iframe-element/iframe_remove_src.html": [ @@ -410370,12 +411107,16 @@ "9ae71a6e73e22a855c69d3269936d71c17d6e9e5", "support" ], + "infrastructure/metadata/infrastructure/testdriver/actions/elementTiming.html.ini": [ + "a06134a6ea427d40aa7b664bde5d4b3d6df24b96", + "support" + ], "infrastructure/metadata/infrastructure/testdriver/actions/eventOrder.html.ini": [ - "07c05be36f26de9e8afe8dfbe0a23a73b4be1254", + "00916c7af3f1ec97692afb727b02dc4f29327a99", "support" ], "infrastructure/metadata/infrastructure/testdriver/actions/multiDevice.html.ini": [ - "04b97a7198c75ba941d315716483aad216e1a283", + "b9fb2596b952ad81b97d7e04b5eb941d37b3b5da", "support" ], "infrastructure/metadata/infrastructure/testdriver/actions/pause.html.ini": [ @@ -410847,7 +411588,7 @@ "support" ], "interfaces/feature-policy.idl": [ - "c09cc33ce14daefd44db0a84c1a9b39264e856a1", + "2a04215801610c36895277b2270c9e9f8efb77f1", "support" ], "interfaces/fetch.idl": [ @@ -411087,7 +411828,7 @@ "support" ], "interfaces/shape-detection-api.idl": [ - "dbdf022e384704961ef9dd4d30714af73e9be913", + "66c58896c300c47206462171b3063baedfff87db", "support" ], "interfaces/speech-api.idl": [ @@ -411123,7 +411864,7 @@ "support" ], "interfaces/wai-aria.idl": [ - "c6ea9591f8d7fb5b0a1651a6d1d5c8c6cab7b0ae", + "21feb78b0b2a2974d95b948fcb7a069f0bab03b8", "support" ], "interfaces/wake-lock.idl": [ @@ -423954,6 +424695,14 @@ "29134d490f7bdfb09255e190fe91576629057c78", "support" ], + "portals/portals-no-referrer.html": [ + "0386272f441a0c2e19452821968a624d3ab16700", + "testharness" + ], + "portals/resources/postmessage-referrer.sub.html": [ + "6897ab0801d8d0408913a5a44c03a022c983121e", + "support" + ], "preload/META.yml": [ "fd10e7d15abd6ed0f4e76581b225ca1e9a248c79", "support" @@ -434483,7 +435232,7 @@ "support" ], "resources/testharness.js": [ - "b08074b96bd64acdec4b0aaead9cf957aa725e85", + "b53ceaf02a375e8ed260be8ff9f212249b2eaf5d", "support" ], "resources/testharness.js.headers": [ @@ -439067,7 +439816,7 @@ "support" ], "signed-exchange/resources/fallback-to-another-sxg.sxg.headers": [ - "ab188e54e05ba06476ee3ebad276bd411474a0b8", + "ca41178420c5b2adf70c439435d40b6370535330", "support" ], "signed-exchange/resources/generate-test-certs.sh": [ @@ -439075,7 +439824,7 @@ "support" ], "signed-exchange/resources/generate-test-sxgs.sh": [ - "6336ba3f797386a81ecc8168f9d5e98ea798152b", + "a31ce6810d33c5a82b4453b71cb7e4d8248e914e", "support" ], "signed-exchange/resources/inner-url.html": [ @@ -439087,7 +439836,7 @@ "support" ], "signed-exchange/resources/nested-sxg.sxg.headers": [ - "ab188e54e05ba06476ee3ebad276bd411474a0b8", + "ca41178420c5b2adf70c439435d40b6370535330", "support" ], "signed-exchange/resources/sxg-head-request.sxg": [ @@ -439095,7 +439844,23 @@ "support" ], "signed-exchange/resources/sxg-head-request.sxg.headers": [ - "ab188e54e05ba06476ee3ebad276bd411474a0b8", + "ca41178420c5b2adf70c439435d40b6370535330", + "support" + ], + "signed-exchange/resources/sxg-inner-url-bom.sxg": [ + "ace5abdd0b0f95f31fca8477008c3fce0f333078", + "support" + ], + "signed-exchange/resources/sxg-inner-url-bom.sxg.headers": [ + "ca41178420c5b2adf70c439435d40b6370535330", + "support" + ], + "signed-exchange/resources/sxg-invalid-utf8-inner-url.sxg": [ + "1f697b74b0d787d7cc30420c2cb68d0388d10b20", + "support" + ], + "signed-exchange/resources/sxg-invalid-utf8-inner-url.sxg.headers": [ + "ca41178420c5b2adf70c439435d40b6370535330", "support" ], "signed-exchange/resources/sxg-invalid-validity-url.sxg": [ @@ -439103,7 +439868,7 @@ "support" ], "signed-exchange/resources/sxg-invalid-validity-url.sxg.headers": [ - "ab188e54e05ba06476ee3ebad276bd411474a0b8", + "ca41178420c5b2adf70c439435d40b6370535330", "support" ], "signed-exchange/resources/sxg-location.html": [ @@ -439115,7 +439880,15 @@ "support" ], "signed-exchange/resources/sxg-location.sxg.headers": [ - "ab188e54e05ba06476ee3ebad276bd411474a0b8", + "ca41178420c5b2adf70c439435d40b6370535330", + "support" + ], + "signed-exchange/resources/sxg-utf8-inner-url.sxg": [ + "c8f8a94ef90bed5383bbfc5742759893a1d21798", + "support" + ], + "signed-exchange/resources/sxg-utf8-inner-url.sxg.headers": [ + "ca41178420c5b2adf70c439435d40b6370535330", "support" ], "signed-exchange/resources/sxg-util.js": [ @@ -439134,6 +439907,14 @@ "83b427b6cf19bff8e8c482a3cba7a899dcbe6e73", "testharness" ], + "signed-exchange/sxg-inner-url-bom.tentative.html": [ + "c694a2236ff900bee4eb226dcd8124098668e3c2", + "testharness" + ], + "signed-exchange/sxg-invalid-utf8-inner-url.tentative.html": [ + "bc28d8101cc7ac964850bb88907e5e6cd8d2b90b", + "testharness" + ], "signed-exchange/sxg-invalid-validity-url.tentative.html": [ "7264e48b8b7a508213c2e7290a274d318ad29872", "testharness" @@ -439147,13 +439928,17 @@ "testharness" ], "signed-exchange/sxg-non-secure-origin.tentative.html": [ - "173702971bd23301b400cfaeea26421ac25932f7", + "50a9ce30d80f9e41b6993e368da9f6ac71045cc4", "testharness" ], "signed-exchange/sxg-prefetch-resource-timing.tentative.html": [ "f0dc477e730ed45e32c43b70ca546d9790b6839d", "testharness" ], + "signed-exchange/sxg-utf8-inner-url.tentative.html": [ + "fc33560d296d9f72ee7858692a20bf2763bd957b", + "testharness" + ], "speech-api/META.yml": [ "4d1b42a44d2a6a447f8a47bc079d7e28436843e0", "support" @@ -439351,11 +440136,11 @@ "support" ], "streams/byte-length-queuing-strategy.any.js": [ - "e4ad144cbc37c023100bc4e6ed7b54d9b5e256e5", + "d47e7cd4faa787933920c48d99a75eea98eaefe7", "testharness" ], "streams/count-queuing-strategy.any.js": [ - "00cba3cdc6cdd786da95de184e635a749eb40199", + "20bb4c1842d258f2de7ff3261c4a93c9d427707e", "testharness" ], "streams/piping/abort.any-expected.txt": [ @@ -439363,7 +440148,7 @@ "support" ], "streams/piping/abort.any.js": [ - "6282a154469cbfb1b22b989291a4b4b61ff2ecfd", + "5064533d4defdf22a6a04b4a3f47beceee417f58", "testharness" ], "streams/piping/abort.any.serviceworker-expected.txt": [ @@ -439379,31 +440164,31 @@ "support" ], "streams/piping/close-propagation-backward.any.js": [ - "90f6412641f7e74fd2dbe1b31a614f0fe49dba6d", + "99141e3120ffe2cb81120451434f08bc0d16318d", "testharness" ], "streams/piping/close-propagation-forward.any.js": [ - "da249713d6d2f04135733f66742ede1fa975042b", + "88513482b004ae3a50f103cf74befe9c83d91e8b", "testharness" ], "streams/piping/error-propagation-backward.any.js": [ - "c822b80b643e5baaee358ce535b7d614155076fe", + "da92e8e7d2c1ee7182c76c5ac6a13ce8dee17def", "testharness" ], "streams/piping/error-propagation-forward.any.js": [ - "b04bf88a30ba6ae727c2576250759e4991b723a8", + "113422e5c9fde9da2079403b3121a22975715c90", "testharness" ], "streams/piping/flow-control.any.js": [ - "ff1f81c05f0c9da97f538b99f2f441ab93955ec1", + "05762a428e0c6773afef68819c974f3e6b7be3b3", "testharness" ], "streams/piping/general.any.js": [ - "9ba494532a59c7b09c1876dd5fc7ceed41a78bab", + "250ebc3ece8c7b2d2c9525cd503d79cc89b90d9b", "testharness" ], "streams/piping/multiple-propagation.any.js": [ - "cd7cd5aa5cf7cd8807a2bdad4a4ac520ca98a68b", + "541cfad6243c12114dc683c68ce558e7c4d9a042", "testharness" ], "streams/piping/pipe-through.any-expected.txt": [ @@ -439411,7 +440196,7 @@ "support" ], "streams/piping/pipe-through.any.js": [ - "2b896f515180556c7f0862868fdd6f970c54b9cf", + "868899c72665802f8083d367955a021321c2a3be", "testharness" ], "streams/piping/pipe-through.any.serviceworker-expected.txt": [ @@ -439427,11 +440212,11 @@ "support" ], "streams/piping/then-interception.any.js": [ - "ef0b824c36d9db401b8fafba1b9e08a57c2377bb", + "3c85f6edb25b955645ccc5fedae3f0facdb36a2b", "testharness" ], "streams/piping/transform-streams.any.js": [ - "8cb342920a48f7675afb68c87761c6817020715c", + "368ed79da4786e0206d421d33076fe9fe61a14ba", "testharness" ], "streams/readable-byte-streams/brand-checks.any-expected.txt": [ @@ -439439,7 +440224,7 @@ "support" ], "streams/readable-byte-streams/brand-checks.any.js": [ - "62f51277c41d9e5b45f03322214caf8316d3355d", + "e4d5e26e84385bf6b4d4698444d9233a74b0cb05", "testharness" ], "streams/readable-byte-streams/brand-checks.any.serviceworker-expected.txt": [ @@ -439459,7 +440244,7 @@ "support" ], "streams/readable-byte-streams/construct-byob-request.any.js": [ - "427166f67cf8bd5cf9be598be7cc23b33cf40d79", + "428cdeb76aeab536d083c06e17ea54863fe3072a", "testharness" ], "streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt": [ @@ -439479,7 +440264,7 @@ "support" ], "streams/readable-byte-streams/constructor.any.js": [ - "4033ad460ffbdf982786bc46ed26a6e5878c643e", + "b950e05b12d31dc8188f5114f4852b8be20bd759", "testharness" ], "streams/readable-byte-streams/constructor.any.serviceworker-expected.txt": [ @@ -439499,7 +440284,7 @@ "support" ], "streams/readable-byte-streams/detached-buffers.any.js": [ - "bf1d5c7f146a8f3b2bf06d0c54799c2496baacf2", + "7d87173f0a0035a38c51c5318c1dc28ff45abfb6", "testharness" ], "streams/readable-byte-streams/detached-buffers.any.serviceworker-expected.txt": [ @@ -439519,7 +440304,7 @@ "support" ], "streams/readable-byte-streams/general.any.js": [ - "11a627d7f21419eff86dcb68f258b1b916998474", + "c8f1fb7864e4ad2c9e68d7a1144c16cf67b5a5d5", "testharness" ], "streams/readable-byte-streams/general.any.serviceworker-expected.txt": [ @@ -439539,7 +440324,7 @@ "support" ], "streams/readable-byte-streams/properties.any.js": [ - "255089c200fd140cee3f3b64e5cf264bbe6b1307", + "2d52fd678ab1f602b81295904afdd428a3c736db", "testharness" ], "streams/readable-byte-streams/properties.any.serviceworker-expected.txt": [ @@ -439555,39 +440340,39 @@ "support" ], "streams/readable-streams/bad-strategies.any.js": [ - "9582b29c81117c0e78b27a745a237677fdb15634", + "5dab51ef771ee48e537a5f9a9f8cb7514d411797", "testharness" ], "streams/readable-streams/bad-underlying-sources.any.js": [ - "aee2e82472179ee7c3f45ba54044029db35220b2", + "cde5603f2403452576e4d01426f277921082bcd3", "testharness" ], "streams/readable-streams/brand-checks.any.js": [ - "6c2987adc477461e111363e502a9f792227d4638", + "2906494bdf6b378d07f6fbb916a8f6cb63681b63", "testharness" ], "streams/readable-streams/cancel.any.js": [ - "b3842837a7e42526ac80a82c256c7b1ba5d6c5f0", + "75bd9c7ab24e9b24792df3f0bd520baca83ab419", "testharness" ], "streams/readable-streams/constructor.any.js": [ - "3a66472ea006d42d8fe3a3e15a89b870742824be", + "e0f5edd09eb0a2e07269f0d7c82cb23dd670bb50", "testharness" ], "streams/readable-streams/count-queuing-strategy-integration.any.js": [ - "45959cbd76bbf91c204e745516b29a2143046200", + "a60e70d4baecbe7154098ee6a4df8b1910fed5d8", "testharness" ], "streams/readable-streams/default-reader.any.js": [ - "3fde39292f86f52f15b882064cc168878afd728c", + "7c13b15acb6a4692df0df2427e22cafcc18235a2", "testharness" ], "streams/readable-streams/floating-point-total-queue-size.any.js": [ - "038258c5f580f9ad6e07f45e90050de694b7a93c", + "9e4e54c1ff33fe43372841973d28dbc48cc90686", "testharness" ], "streams/readable-streams/garbage-collection.any.js": [ - "c3353acfba1842e5a95f5568362fc21b68a37916", + "b6f2a7f1d94594bfc3b90e4110eba50e052567e6", "testharness" ], "streams/readable-streams/general.any-expected.txt": [ @@ -439595,7 +440380,7 @@ "support" ], "streams/readable-streams/general.any.js": [ - "5e8a4af76c4671984484a9f5775de29cbc2935af", + "f885ed6dbcdc6983ce1a52f60af492e875503d03", "testharness" ], "streams/readable-streams/general.any.serviceworker-expected.txt": [ @@ -439611,19 +440396,19 @@ "support" ], "streams/readable-streams/patched-global.any.js": [ - "b3d5a33647b11f1cdcff4bd9e4b7d948e4ee1792", + "fa49249a9b5e78548892d6405460b88eb6e68361", "testharness" ], "streams/readable-streams/reentrant-strategies.any.js": [ - "05471cee26ccbd26e8261b6fcf5fda233a742310", + "7724ea63d3747e4fdf8dcd418889d3c2160d8036", "testharness" ], "streams/readable-streams/tee.any.js": [ - "1b25ca7f8247da592357ec002d5bc5cbf059ae76", + "a06e2491efc5f3fa0cf85f27aae973a4a43e61ea", "testharness" ], "streams/readable-streams/templated.any.js": [ - "5926c0818d91fd69245d15f79bbe3123c8882160", + "b5cc0b30ed36df99fc3f26227166a4d3ddcdfe08", "testharness" ], "streams/resources/constructor-ordering.js": [ @@ -439647,95 +440432,95 @@ "support" ], "streams/transform-streams/backpressure.any.js": [ - "44d91b7f995925c7434409d73da1ab924c94e645", + "a604096ccc1f3342728cfdcc8a65244a418bcbf3", "testharness" ], "streams/transform-streams/brand-checks.any.js": [ - "2fbcd039c31bf6c98519c949bc46303537f364dc", + "79a5d55e1b3367e7cba369ee117c9c8813e38aeb", "testharness" ], "streams/transform-streams/constructor.any.js": [ - "69e9be3a1e93626d191d2da3a8994997c0037214", + "dfa966e03407edbfefdd71ba8954ba8b07aebc10", "testharness" ], "streams/transform-streams/errors.any.js": [ - "a0a8e20413a29ee0629f78b9d70395e6aa6f0644", + "53a4a49984b700040793d9c71567345e1180cab8", "testharness" ], "streams/transform-streams/flush.any.js": [ - "df0cc962a8552e6b1d1e8b8ff6dd790af04fd89a", + "ef08967865f8fa647abeeaa53213ba1ba49d15f0", "testharness" ], "streams/transform-streams/general.any.js": [ - "0b012a91a90f3adce8d3a5702fedd942b132a91c", + "537001edae99e0be56d39404e6cc366c3443274d", "testharness" ], "streams/transform-streams/lipfuzz.any.js": [ - "a5f09ee2d60ebfd47349db2d834e02ff2117110c", + "c31d0e46468494930cd0bc545654dcb3d9e2ffde", "testharness" ], "streams/transform-streams/patched-global.any.js": [ - "34a602e1ca922d7fc036870de4839fc68756f272", + "52d44a347ae0005de95ab43a06ac1d0adddc757e", "testharness" ], "streams/transform-streams/properties.any.js": [ - "3208cfe055aac1c61c33a019e848ccf2548769bc", + "892d66169284237f967b33ec5c87a4b74b79a508", "testharness" ], "streams/transform-streams/reentrant-strategies.any.js": [ - "d9e2937d558885204ac5ddc57ac20784f00157af", + "c18d6d102d5299a4aac628fcb47973f6cb6be58a", "testharness" ], "streams/transform-streams/strategies.any.js": [ - "894d1fa8b761c0b6fb1655fa5f6cdc55116b28a1", + "9ebfec7358e53e60061f33de61bdcd4bc4fb4243", "testharness" ], "streams/transform-streams/terminate.any.js": [ - "231adbd3e0c4b3a50c696a34dff51d89b33ff653", + "2bf9eabed8410c9352a70163c8f40e25811dfd0f", "testharness" ], "streams/writable-streams/aborting.any.js": [ - "10753fe02aade0d13948957af7f527e9605c8489", + "18fb58edf6de41d5d6208997d94fb5ed9e00a1e0", "testharness" ], "streams/writable-streams/bad-strategies.any.js": [ - "5832d45cd1cd70dea4aaa7f94f89a98920f5a69b", + "d67ee6b5039dc98e5093aef0c3f2820462112a4c", "testharness" ], "streams/writable-streams/bad-underlying-sinks.any.js": [ - "e523c46129b99d4769114e647a96bfbb04f47af4", + "ed04b3c0a17fcd9902054e0d844171b9baa41c18", "testharness" ], "streams/writable-streams/brand-checks.any.js": [ - "06e75cc38af9034529ef23dd9671b7c99c239add", + "968cb4c653aafdc3b906f0574f5fb2f08d5f7b3a", "testharness" ], "streams/writable-streams/byte-length-queuing-strategy.any.js": [ - "3c8c8bfc38699556dfb1e764f40b432e52a04be4", + "5edd41cc31d8d76d2cc91d7c5b2e850dc9ee43f1", "testharness" ], "streams/writable-streams/close.any.js": [ - "79f1b03e5351cf3804563e65f39c13eb7503d01a", + "21f361f1f30b9967eff55ec84d7818925cf4f69a", "testharness" ], "streams/writable-streams/constructor.any.js": [ - "937991040289588b40e0ca3fdbb0c13cd488f683", + "97cda9cedac9aaae87cfa23e63c7667b15955734", "testharness" ], "streams/writable-streams/count-queuing-strategy.any.js": [ - "f48ec8db113a27bca04f71a58df91b029473b08b", + "e8d9ca8a98dcc449ca6bd9cdbb515b16761460b7", "testharness" ], "streams/writable-streams/error.any.js": [ - "e0a87a6178734d4556971fef62a1a8cbff809b2c", + "76b5c8a95decaa6bab61047f656635ec3aa7ab7f", "testharness" ], "streams/writable-streams/floating-point-total-queue-size.any.js": [ - "a06f4a12387ea765b83c2d8cb0cbd8225171c020", + "580c8cbcbf9efa09c52446350644e0fdcaf1a090", "testharness" ], "streams/writable-streams/general.any.js": [ - "6ddae1f8a3e9dda92224d08344d5c5ffb1ae3dbc", + "253909f27b42406f099f4539311fde0280a482fa", "testharness" ], "streams/writable-streams/properties.any-expected.txt": [ @@ -439743,7 +440528,7 @@ "support" ], "streams/writable-streams/properties.any.js": [ - "fe798a7d8f4045e72541d8434b52203361906f23", + "b991795a1898e9b1d479d1497009b889f0d786ce", "testharness" ], "streams/writable-streams/properties.any.serviceworker-expected.txt": [ @@ -439759,15 +440544,15 @@ "support" ], "streams/writable-streams/reentrant-strategy.any.js": [ - "c8c59370a76dd4a58a7d5149520fe1bf0a954d56", + "8fa31f9d124bb31ea13c1a5245aed491964e0830", "testharness" ], "streams/writable-streams/start.any.js": [ - "69cc131c065a2a7923ea1974369b739eb517f71c", + "0a1095b25062b2b46d8632d6239e60dc743d6604", "testharness" ], "streams/writable-streams/write.any.js": [ - "19299f01d80b69d9da3e41e9729b5d5b41eeb00f", + "85c7f8ceb969b02f1928ad9992c31b94527e369e", "testharness" ], "subresource-integrity/META.yml": [ @@ -440130,6 +440915,10 @@ "e92e2cf6410ba4071baa81c18ec4462ba60b42dd", "testharness" ], + "svg/geometry/parsing/sizing-properties-computed.svg": [ + "93d6815de3b64f913f3f11d8ce0303ac68229e6d", + "testharness" + ], "svg/geometry/parsing/width-computed-expected.txt": [ "f23fb13cd26245410dcdf369691909306c9757ce", "support" @@ -446239,11 +447028,11 @@ "support" ], "webrtc/RTCPeerConnection-iceConnectionState-expected.txt": [ - "e3cf3163468c69d9f68c8887abd4bbc1039bc86b", + "b28601423de0b987c27db05d4b4061ece60f0129", "support" ], "webrtc/RTCPeerConnection-iceConnectionState.html": [ - "4071033a3c9eff6e5b848531127c1b70ee90bb20", + "b647b3d3e35e31f16b33422f67cb30b917d1d0af", "testharness" ], "webrtc/RTCPeerConnection-iceGatheringState-expected.txt": [ @@ -446598,6 +447387,10 @@ "9579dd4d4f81be24c065529728183cb2287d15b6", "testharness" ], + "webrtc/RTCTrackEvent-fire.html": [ + "2e226c35174ec2030550cbd1788737573ca49eeb", + "testharness" + ], "webrtc/coverage/RTCDTMFSender.txt": [ "aa30021323870669c8aada66f481168bf4cd4c7b", "support" @@ -451259,7 +452052,7 @@ "support" ], "webxr/idlharness.https.window-expected.txt": [ - "51e4af40edabe2c90c4527552ec8c51965f82b19", + "27484b4ad784a35100c15fb14836ede5896d1f58", "support" ], "webxr/idlharness.https.window.js": [ @@ -451279,7 +452072,7 @@ "support" ], "webxr/resources/webxr_util.js": [ - "5437513b304cb517a67c8e13f6137759d87156be", + "ee6e67f4c3d090015ead8b8718c2a836871a68ba", "support" ], "webxr/webGLCanvasContext_create_with_xrdevice.https.html": [ @@ -451347,11 +452140,11 @@ "testharness" ], "webxr/xrSession_requestAnimationFrame_data_valid.https.html": [ - "702932ae62cedef340ccbcfd068dc993a40b521b", + "4093d7afdb3ad08533521ffb096a92a461c13747", "testharness" ], "webxr/xrSession_requestAnimationFrame_getViewerPose.https.html": [ - "195e653ccfc59aaca582d223072001dc1049309a", + "c6d5c1024fbadfa95af7a70216b2338fc43aef1b", "testharness" ], "webxr/xrSession_requestFrameOfReference.https.html": [
diff --git a/third_party/blink/web_tests/external/wpt/bluetooth/idl/idlharness.tentative.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/bluetooth/idl/idlharness.tentative.https.window-expected.txt index e5d18e75c..6c2db97b 100644 --- a/third_party/blink/web_tests/external/wpt/bluetooth/idl/idlharness.tentative.https.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/bluetooth/idl/idlharness.tentative.https.window-expected.txt
@@ -1,10 +1,10 @@ This is a testharness.js-based test. PASS idl_test setup 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: existence and properties of interface object 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 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 @@ -59,32 +59,32 @@ FAIL BluetoothDevice interface: attribute onserviceadded assert_true: The prototype object must have a property "onserviceadded" expected true got false FAIL BluetoothDevice interface: attribute onservicechanged assert_true: The prototype object must have a property "onservicechanged" expected true got false FAIL BluetoothDevice interface: attribute onserviceremoved assert_true: The prototype object must have a property "onserviceremoved" expected true got false -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 -FAIL BluetoothAdvertisingEvent interface: attribute uuids assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing -FAIL BluetoothAdvertisingEvent interface: attribute name assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing -FAIL BluetoothAdvertisingEvent interface: attribute appearance assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing -FAIL BluetoothAdvertisingEvent interface: attribute txPower assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing -FAIL BluetoothAdvertisingEvent interface: attribute rssi assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing -FAIL BluetoothAdvertisingEvent interface: attribute manufacturerData assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing -FAIL BluetoothAdvertisingEvent interface: attribute serviceData assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing +PASS BluetoothManufacturerDataMap interface: existence and properties of interface object +PASS BluetoothManufacturerDataMap interface object length +PASS BluetoothManufacturerDataMap interface object name +PASS BluetoothManufacturerDataMap interface: existence and properties of interface prototype object +PASS BluetoothManufacturerDataMap interface: existence and properties of interface prototype object's "constructor" property +PASS BluetoothManufacturerDataMap interface: existence and properties of interface prototype object's @@unscopables property +PASS BluetoothServiceDataMap interface: existence and properties of interface object +PASS BluetoothServiceDataMap interface object length +PASS BluetoothServiceDataMap interface object name +PASS BluetoothServiceDataMap interface: existence and properties of interface prototype object +PASS BluetoothServiceDataMap interface: existence and properties of interface prototype object's "constructor" property +PASS BluetoothServiceDataMap interface: existence and properties of interface prototype object's @@unscopables property +PASS BluetoothAdvertisingEvent interface: existence and properties of interface object +FAIL BluetoothAdvertisingEvent interface object length assert_equals: wrong value for BluetoothAdvertisingEvent.length expected 2 but got 0 +PASS BluetoothAdvertisingEvent interface object name +PASS BluetoothAdvertisingEvent interface: existence and properties of interface prototype object +PASS BluetoothAdvertisingEvent interface: existence and properties of interface prototype object's "constructor" property +PASS BluetoothAdvertisingEvent interface: existence and properties of interface prototype object's @@unscopables property +PASS BluetoothAdvertisingEvent interface: attribute device +PASS BluetoothAdvertisingEvent interface: attribute uuids +PASS BluetoothAdvertisingEvent interface: attribute name +PASS BluetoothAdvertisingEvent interface: attribute appearance +PASS BluetoothAdvertisingEvent interface: attribute txPower +PASS BluetoothAdvertisingEvent interface: attribute rssi +PASS BluetoothAdvertisingEvent interface: attribute manufacturerData +PASS BluetoothAdvertisingEvent interface: attribute serviceData FAIL BluetoothAdvertisingEvent must be primary interface of event assert_equals: wrong typeof object expected "object" but got "undefined" FAIL Stringification of event assert_equals: wrong typeof object expected "object" but got "undefined" FAIL BluetoothAdvertisingEvent interface: event must inherit property "device" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
diff --git a/third_party/blink/web_tests/external/wpt/bluetooth/resources/bluetooth-helpers.js b/third_party/blink/web_tests/external/wpt/bluetooth/resources/bluetooth-helpers.js index c4e2607..64a20c2 100644 --- a/third_party/blink/web_tests/external/wpt/bluetooth/resources/bluetooth-helpers.js +++ b/third_party/blink/web_tests/external/wpt/bluetooth/resources/bluetooth-helpers.js
@@ -261,6 +261,12 @@ () => navigator.bluetooth.requestDevice.apply(navigator.bluetooth, args)); } +// Calls requestLEScan() in a context that's 'allowed to show a popup'. +function requestLEScanWithTrustedClick() { + return callWithTrustedClick( + () => navigator.bluetooth.requestLEScan.apply(navigator.bluetooth)); +} + // errorUUID(alias) returns a UUID with the top 32 bits of // '00000000-97e5-4cd7-b9f1-f5a427670c59' replaced with the bits of |alias|. // For example, errorUUID(0xDEADBEEF) returns
diff --git a/third_party/blink/web_tests/external/wpt/bluetooth/resources/bluetooth-scanning-helpers.js b/third_party/blink/web_tests/external/wpt/bluetooth/resources/bluetooth-scanning-helpers.js new file mode 100644 index 0000000..9b173e63 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/bluetooth/resources/bluetooth-scanning-helpers.js
@@ -0,0 +1,42 @@ +'use strict'; + +const company_id = '224'; +const data = new TextEncoder().encode('foo'); +const manufacturerDataMap = {[company_id]: data}; +const health_uuid = health_thermometer.uuid; +const serviceDataMap = {[health_uuid]: data}; +const scanRecord = { + name: 'Health Thermometer', + uuids: ['generic_access', health_uuid], + txPower: 20, + appearance: 100, + manufacturerData: manufacturerDataMap, + serviceData: serviceDataMap, +}; +const scanResult = { + deviceAddress: '09:09:09:09:09:09', + rssi: 100, + scanRecord: scanRecord, +}; + +function verifyBluetoothAdvertisingEvent(e) { + assert_equals(e.constructor.name, 'BluetoothAdvertisingEvent') + assert_equals(e.device.name, scanRecord.name) + assert_equals(e.name, scanRecord.name) + assert_array_equals(e.uuids, + ["00001800-0000-1000-8000-00805f9b34fb", + "00001809-0000-1000-8000-00805f9b34fb"]) + assert_equals(e.txPower, 20) + assert_equals(e.rssi, 100) + + assert_equals(e.manufacturerData.constructor.name, + 'BluetoothManufacturerDataMap') + assert_equals(data[0], e.manufacturerData.get(224).getUint8(0)) + assert_equals(data[1], e.manufacturerData.get(224).getUint8(1)) + assert_equals(data[2], e.manufacturerData.get(224).getUint8(2)) + + assert_equals(e.serviceData.constructor.name, 'BluetoothServiceDataMap') + assert_equals(data[0], e.serviceData.get(health_uuid).getUint8(0)) + assert_equals(data[1], e.serviceData.get(health_uuid).getUint8(1)) + assert_equals(data[2], e.serviceData.get(health_uuid).getUint8(2)) +} \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-area-computed-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-area-computed-expected.txt new file mode 100644 index 0000000..a56967d7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-area-computed-expected.txt
@@ -0,0 +1,32 @@ +This is a testharness.js-based test. +PASS Property grid-area value 'auto / auto / auto / auto' computes to 'auto / auto / auto / auto' +PASS Property grid-row value 'auto / auto' computes to 'auto / auto' +PASS Property grid-column-end value 'auto' computes to 'auto' +PASS Property grid-row value '-zπ' computes to '-zπ / -zπ' +PASS Property grid-row-start value 'AZ' computes to 'AZ' +PASS Property grid-column-start value '-_π' computes to '-_π' +PASS Property grid-row-end value '_9' computes to '_9' +PASS Property grid-area value '1 / 90 -a- / auto / auto' computes to '1 / 90 -a- / auto / auto' +PASS Property grid-row value '2 az / auto' computes to '2 az / auto' +PASS Property grid-column value '9 / -19 zA' computes to '9 / -19 zA' +PASS Property grid-row-start value '-19' computes to '-19' +PASS Property grid-row-start value '9 -Z_' computes to '9 -Z_' +PASS Property grid-column-start value '-44 Z' computes to '-44 Z' +PASS Property grid-row-end value '1 -πA' computes to '1 -πA' +PASS Property grid-column-end value '5 π_' computes to '5 π_' +PASS Property grid-area value 'span 2 i / auto / auto / auto' computes to 'span 2 i / auto / auto / auto' +PASS Property grid-row value 'span 2 / auto' computes to 'span 2 / auto' +PASS Property grid-column-start value 'span 1 i' computes to 'span 1 i' +PASS Property grid-row-end value 'span 2 i' computes to 'span 2 i' +PASS Property grid-column-end value 'span 2' computes to 'span 2' +FAIL Property grid-row-start value 'span i' computes to 'span i' assert_equals: expected "span i" but got "span 1 i" +FAIL Property grid-row value 'span i / auto' computes to 'span i / auto' assert_equals: expected "span i / auto" but got "span 1 i / auto" +PASS Property grid-area value 'auto / i / auto / i' computes to 'auto / i / auto / i' +PASS Property grid-area value 'auto / i / 2 j' computes to 'auto / i / 2 j / i' +PASS Property grid-area value 'auto / i / 2 j / span 3 k' computes to 'auto / i / 2 j / span 3 k' +PASS Property grid-row value 'auto / i' computes to 'auto / i' +PASS Property grid-column value '2 j / span 3 k' computes to '2 j / span 3 k' +PASS Property grid-column-end value '\31st' computes to '\31 st' +PASS Property grid-column-end value '\31 st' computes to '\31 st' +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-area-computed.html b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-area-computed.html new file mode 100644 index 0000000..731b7ebd --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-area-computed.html
@@ -0,0 +1,61 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: getComputedValue().gridArea</title> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#placement"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/computed-testcommon.js"></script> +</head> +<body> +<div id="target"></div> +<script> +// auto +test_computed_value("grid-area", "auto / auto / auto / auto"); +test_computed_value("grid-row", "auto / auto"); +test_computed_value("grid-column-end", "auto"); + +// <custom-ident> +test_computed_value("grid-row", "-zπ", "-zπ / -zπ"); +test_computed_value("grid-row-start", "AZ"); +test_computed_value("grid-column-start", "-_π"); +test_computed_value("grid-row-end", "_9"); + + +// <integer> && <custom-ident>? +test_computed_value("grid-area", "1 / 90 -a- / auto / auto"); +test_computed_value("grid-row", "2 az / auto"); +test_computed_value("grid-column", "9 / -19 zA"); +test_computed_value("grid-row-start", "-19"); +test_computed_value("grid-row-start", "9 -Z_"); +test_computed_value("grid-column-start", "-44 Z"); +test_computed_value("grid-row-end", "1 -πA"); +test_computed_value("grid-column-end", "5 π_"); + +// span && [ <integer> || <custom-ident> ] +test_computed_value("grid-area", "span 2 i / auto / auto / auto"); +test_computed_value("grid-row", "span 2 / auto"); +test_computed_value("grid-column-start", "span 1 i"); +test_computed_value("grid-row-end", "span 2 i"); +test_computed_value("grid-column-end", "span 2"); + +// https://github.com/w3c/csswg-drafts/issues/3448 +test_computed_value("grid-row-start", "span i"); +test_computed_value("grid-row", "span i / auto"); + +// <grid-line> [ / <grid-line> ]{0,3} +test_computed_value("grid-area", "auto / i / auto / i"); +test_computed_value("grid-area", "auto / i / 2 j", "auto / i / 2 j / i"); +test_computed_value("grid-area", "auto / i / 2 j / span 3 k"); +test_computed_value("grid-row", "auto / i"); +test_computed_value("grid-column", "2 j / span 3 k"); + + +// https://github.com/w3c/csswg-drafts/issues/2858 +test_computed_value("grid-column-end", "\\31st", "\\31 st"); +test_computed_value("grid-column-end", "\\31 st", "\\31 st"); + +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-auto-columns-computed.html b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-auto-columns-computed.html new file mode 100644 index 0000000..6aea96a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-auto-columns-computed.html
@@ -0,0 +1,58 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: getComputedValue().gridAutoColumns</title> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#propdef-grid-auto-columns"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/computed-testcommon.js"></script> +</head> +<body> +<div id="target"></div> +<style> + #target { + font-size: 40px; + } +</style> +<script> +// <track-breadth> +// <track-breadth> = <length-percentage> | <flex> | min-content | max-content | auto +test_computed_value("grid-auto-columns", "1px"); +test_computed_value("grid-auto-columns", "calc(10px + 0.5em)", "30px"); +test_computed_value("grid-auto-columns", "calc(10px - 0.5em)", "0px"); +test_computed_value("grid-auto-columns", "4%"); +test_computed_value("grid-auto-columns", "5fr"); +test_computed_value("grid-auto-columns", "min-content"); +test_computed_value("grid-auto-columns", "max-content"); +test_computed_value("grid-auto-columns", "auto"); + +// minmax( <inflexible-breadth> , <track-breadth> ) +// <inflexible-breadth> = <length-percentage> | min-content | max-content | auto +test_computed_value("grid-auto-columns", "minmax(1px, 5fr)"); +test_computed_value("grid-auto-columns", "minmax(calc(10px + 0.5em), max-content)", "minmax(30px, max-content)"); +test_computed_value("grid-auto-columns", "minmax(calc(10px - 0.5em), max-content)", "minmax(0px, max-content)"); +test_computed_value("grid-auto-columns", "minmax(4%, auto)"); +test_computed_value("grid-auto-columns", "minmax(min-content, calc(10px + 0.5em))", "minmax(min-content, 30px)"); +test_computed_value("grid-auto-columns", "minmax(auto, 4%)"); + +// fit-content( <length-percentage> ) +test_computed_value("grid-auto-columns", "fit-content(1px)"); +test_computed_value("grid-auto-columns", "fit-content(calc(10px + 0.5em))", "fit-content(30px)"); +test_computed_value("grid-auto-columns", "fit-content(calc(10px - 0.5em))", "fit-content(0px)"); +test_computed_value("grid-auto-columns", "fit-content(4%)"); + +// 0 +test_computed_value("grid-auto-columns", "0px"); +test_computed_value("grid-auto-columns", "0%"); +test_computed_value("grid-auto-columns", "0fr"); +test_computed_value("grid-auto-columns", "minmax(auto, 0%)"); +test_computed_value("grid-auto-columns", "fit-content(0px)"); + +// <track-size>+ +// https://bugzilla.mozilla.org/show_bug.cgi?id=1339672 +test_computed_value("grid-auto-columns", "1px 2px 3px 0px"); +test_computed_value("grid-auto-columns", "fit-content(1px) minmax(2px, 3px) 4px"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-auto-flow-computed.html b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-auto-flow-computed.html new file mode 100644 index 0000000..7484f62 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-auto-flow-computed.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: getComputedValue().gridAutoFlow</title> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#propdef-grid-auto-flow"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/computed-testcommon.js"></script> +</head> +<body> +<div id="target"></div> +<script> +test_computed_value("grid-auto-flow", "row"); +test_computed_value("grid-auto-flow", "column"); +test_computed_value("grid-auto-flow", "row dense"); +test_computed_value("grid-auto-flow", "column dense"); + +test_computed_value("grid-auto-flow", "dense row", "row dense"); +test_computed_value("grid-auto-flow", "dense column", "column dense"); + +test_computed_value("grid-auto-flow", "dense", "row dense"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-auto-rows-computed.html b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-auto-rows-computed.html new file mode 100644 index 0000000..071c1692 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-auto-rows-computed.html
@@ -0,0 +1,58 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: getComputedValue().gridAutoRows</title> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#propdef-grid-auto-rows"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/computed-testcommon.js"></script> +</head> +<body> +<div id="target"></div> +<style> + #target { + font-size: 40px; + } +</style> +<script> +// <track-breadth> +// <track-breadth> = <length-percentage> | <flex> | min-content | max-content | auto +test_computed_value("grid-auto-rows", "1px"); +test_computed_value("grid-auto-rows", "calc(10px + 0.5em)", "30px"); +test_computed_value("grid-auto-rows", "calc(10px - 0.5em)", "0px"); +test_computed_value("grid-auto-rows", "4%"); +test_computed_value("grid-auto-rows", "5fr"); +test_computed_value("grid-auto-rows", "min-content"); +test_computed_value("grid-auto-rows", "max-content"); +test_computed_value("grid-auto-rows", "auto"); + +// minmax( <inflexible-breadth> , <track-breadth> ) +// <inflexible-breadth> = <length-percentage> | min-content | max-content | auto +test_computed_value("grid-auto-rows", "minmax(1px, 5fr)"); +test_computed_value("grid-auto-rows", "minmax(calc(10px + 0.5em), max-content)", "minmax(30px, max-content)"); +test_computed_value("grid-auto-rows", "minmax(calc(10px - 0.5em), max-content)", "minmax(0px, max-content)"); +test_computed_value("grid-auto-rows", "minmax(4%, auto)"); +test_computed_value("grid-auto-rows", "minmax(min-content, calc(10px + 0.5em))", "minmax(min-content, 30px)"); +test_computed_value("grid-auto-rows", "minmax(auto, 4%)"); + +// fit-content( <length-percentage> ) +test_computed_value("grid-auto-rows", "fit-content(1px)"); +test_computed_value("grid-auto-rows", "fit-content(calc(10px + 0.5em))", "fit-content(30px)"); +test_computed_value("grid-auto-rows", "fit-content(calc(10px - 0.5em))", "fit-content(0px)"); +test_computed_value("grid-auto-rows", "fit-content(4%)"); + +// 0 +test_computed_value("grid-auto-rows", "0px"); +test_computed_value("grid-auto-rows", "0%"); +test_computed_value("grid-auto-rows", "0fr"); +test_computed_value("grid-auto-rows", "minmax(auto, 0%)"); +test_computed_value("grid-auto-rows", "fit-content(0px)"); + +// <track-size>+ +// https://bugzilla.mozilla.org/show_bug.cgi?id=1339672 +test_computed_value("grid-auto-rows", "1px 2px 3px 0px"); +test_computed_value("grid-auto-rows", "fit-content(1px) minmax(2px, 3px) 4px"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-template-areas-computed.html b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-template-areas-computed.html new file mode 100644 index 0000000..84627f8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/parsing/grid-template-areas-computed.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: getComputedValue().gridTemplateAreas</title> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#propdef-grid-template-areas"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/computed-testcommon.js"></script> +</head> +<body> +<div id="target"></div> +<script> +test_computed_value("grid-template-areas", "none"); +test_computed_value("grid-template-areas", '"first"'); +test_computed_value("grid-template-areas", '"first second"'); +test_computed_value("grid-template-areas", '"1st 2nd 3rd"'); +test_computed_value("grid-template-areas", '"first second" "third fourth"'); +test_computed_value("grid-template-areas", '"first second" "third ." "1st 2nd" "3rd 4th"'); + +// https://github.com/w3c/csswg-drafts/issues/3261 +test_computed_value("grid-template-areas", '" a \t b "', '"a b"'); +test_computed_value("grid-template-areas", '"c\td"', '"c d"'); +test_computed_value("grid-template-areas", '"first ..."', '"first ."'); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/block-size-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/block-size-invalid.html new file mode 100644 index 0000000..37d88907 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/block-size-invalid.html
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing block-size with invalid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical-1/#dimension-properties"> +<meta name="assert" content="block-size supports the full grammar 'auto | <length-percentage> | min-content | max-content | fit-content(<length-percentage>)'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_invalid_value("block-size", "none"); + +test_invalid_value("block-size", "min-content available"); +test_invalid_value("block-size", "max-content 10px"); +test_invalid_value("block-size", "20% available"); + +test_invalid_value("block-size", "-10px"); +test_invalid_value("block-size", "-20%"); +test_invalid_value("block-size", "60"); +test_invalid_value("block-size", "10px 20%"); + +test_invalid_value("block-size", "10px border-box"); +test_invalid_value("block-size", "content-box 20%"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/block-size-valid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/block-size-valid.html new file mode 100644 index 0000000..47170e4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/block-size-valid.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing block-size with valid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical-1/#dimension-properties"> +<meta name="assert" content="block-size supports the full grammar 'auto | <length-percentage> | min-content | max-content | fit-content(<length-percentage>)'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_valid_value("block-size", "auto"); + +test_valid_value("block-size", "10px"); +test_valid_value("block-size", "20%"); +test_valid_value("block-size", "calc(2em + 3ex)"); + +test_valid_value("block-size", "min-content"); +test_valid_value("block-size", "max-content"); + +// The following are not yet supported by browsers: +// test_valid_value("block-size", "fit-content(100px)"); +// test_valid_value("block-size", "fit-content(calc(10% + 10px))"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/inline-size-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/inline-size-invalid.html new file mode 100644 index 0000000..d3d5d3f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/inline-size-invalid.html
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing inline-size with invalid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical-1/#dimension-properties"> +<meta name="assert" content="inline-size supports the full grammar 'auto | <length-percentage> | min-content | max-content | fit-content(<length-percentage>)'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_invalid_value("inline-size", "none"); + +test_invalid_value("inline-size", "min-content available"); +test_invalid_value("inline-size", "max-content 10px"); +test_invalid_value("inline-size", "20% available"); + +test_invalid_value("inline-size", "-10px"); +test_invalid_value("inline-size", "-20%"); +test_invalid_value("inline-size", "60"); +test_invalid_value("inline-size", "10px 20%"); + +test_invalid_value("inline-size", "10px border-box"); +test_invalid_value("inline-size", "content-box 20%"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/inline-size-valid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/inline-size-valid.html new file mode 100644 index 0000000..e785b46 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/inline-size-valid.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing inline-size with valid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical-1/#dimension-properties"> +<meta name="assert" content="inline-size supports the full grammar 'auto | <length-percentage> | min-content | max-content | fit-content(<length-percentage>)'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_valid_value("inline-size", "auto"); + +test_valid_value("inline-size", "10px"); +test_valid_value("inline-size", "20%"); +test_valid_value("inline-size", "calc(2em + 3ex)"); + +test_valid_value("inline-size", "min-content"); +test_valid_value("inline-size", "max-content"); + +// The following are not yet supported by browsers: +// test_valid_value("inline-size", "fit-content(100px)"); +// test_valid_value("inline-size", "fit-content(calc(10% + 10px))"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/max-block-size-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/max-block-size-invalid.html new file mode 100644 index 0000000..adcf6e49 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/max-block-size-invalid.html
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing max-block-size with invalid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical-1/#dimension-properties"> +<meta name="assert" content="max-block-size supports the full grammar 'none | <length-percentage> | min-content | max-content | fit-content(<length-percentage>)'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_invalid_value("max-block-size", "auto"); + +test_invalid_value("max-block-size", "min-content available"); +test_invalid_value("max-block-size", "max-content 10px"); +test_invalid_value("max-block-size", "20% available"); + +test_invalid_value("max-block-size", "-10px"); +test_invalid_value("max-block-size", "-20%"); +test_invalid_value("max-block-size", "60"); +test_invalid_value("max-block-size", "10px 20%"); + +test_invalid_value("max-block-size", "10px border-box"); +test_invalid_value("max-block-size", "content-box 20%"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/max-block-size-valid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/max-block-size-valid.html new file mode 100644 index 0000000..75b5c6f5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/max-block-size-valid.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing max-block-size with valid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical-1/#dimension-properties"> +<meta name="assert" content="max-block-size supports the full grammar 'none | <length-percentage> | min-content | max-content | fit-content(<length-percentage>)'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_valid_value("max-block-size", "none"); + +test_valid_value("max-block-size", "10px"); +test_valid_value("max-block-size", "20%"); +test_valid_value("max-block-size", "calc(2em + 3ex)"); + +test_valid_value("max-block-size", "min-content"); +test_valid_value("max-block-size", "max-content"); + +// The following are not yet supported by browsers: +// test_valid_value("max-block-size", "fit-content(100px)"); +// test_valid_value("max-block-size", "fit-content(calc(10% + 10px))"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/max-inline-size-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/max-inline-size-invalid.html new file mode 100644 index 0000000..fa695551 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/max-inline-size-invalid.html
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing max-inline-size with invalid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical-1/#dimension-properties"> +<meta name="assert" content="max-inline-size supports the full grammar 'none | <length-percentage> | min-content | max-content | fit-content(<length-percentage>)'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_invalid_value("max-inline-size", "auto"); + +test_invalid_value("max-inline-size", "min-content available"); +test_invalid_value("max-inline-size", "max-content 10px"); +test_invalid_value("max-inline-size", "20% available"); + +test_invalid_value("max-inline-size", "-10px"); +test_invalid_value("max-inline-size", "-20%"); +test_invalid_value("max-inline-size", "60"); +test_invalid_value("max-inline-size", "10px 20%"); + +test_invalid_value("max-inline-size", "10px border-box"); +test_invalid_value("max-inline-size", "content-box 20%"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/max-inline-size-valid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/max-inline-size-valid.html new file mode 100644 index 0000000..19d5829 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/max-inline-size-valid.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing max-inline-size with valid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical-1/#dimension-properties"> +<meta name="assert" content="max-inline-size supports the full grammar 'none | <length-percentage> | min-content | max-content | fit-content(<length-percentage>)'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_valid_value("max-inline-size", "none"); + +test_valid_value("max-inline-size", "10px"); +test_valid_value("max-inline-size", "20%"); +test_valid_value("max-inline-size", "calc(2em + 3ex)"); + +test_valid_value("max-inline-size", "min-content"); +test_valid_value("max-inline-size", "max-content"); + +// The following are not yet supported by browsers: +// test_valid_value("max-inline-size", "fit-content(100px)"); +// test_valid_value("max-inline-size", "fit-content(calc(10% + 10px))"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/min-block-size-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/min-block-size-invalid.html new file mode 100644 index 0000000..325dc2e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/min-block-size-invalid.html
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing min-block-size with invalid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical-1/#dimension-properties"> +<meta name="assert" content="min-block-size supports the full grammar 'auto | <length-percentage> | min-content | max-content | fit-content(<length-percentage>)'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_invalid_value("min-block-size", "none"); + +test_invalid_value("min-block-size", "min-content available"); +test_invalid_value("min-block-size", "max-content 10px"); +test_invalid_value("min-block-size", "20% available"); + +test_invalid_value("min-block-size", "-10px"); +test_invalid_value("min-block-size", "-20%"); +test_invalid_value("min-block-size", "60"); +test_invalid_value("min-block-size", "10px 20%"); + +test_invalid_value("min-block-size", "10px border-box"); +test_invalid_value("min-block-size", "content-box 20%"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/min-block-size-valid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/min-block-size-valid.html new file mode 100644 index 0000000..5a5d4a4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/min-block-size-valid.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing min-block-size with valid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical-1/#dimension-properties"> +<meta name="assert" content="min-block-size supports the full grammar 'auto | <length-percentage> | min-content | max-content | fit-content(<length-percentage>)'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_valid_value("min-block-size", "auto"); + +test_valid_value("min-block-size", "10px"); +test_valid_value("min-block-size", "20%"); +test_valid_value("min-block-size", "calc(2em + 3ex)"); + +test_valid_value("min-block-size", "min-content"); +test_valid_value("min-block-size", "max-content"); + +// The following are not yet supported by browsers: +// test_valid_value("min-block-size", "fit-content(100px)"); +// test_valid_value("min-block-size", "fit-content(calc(10% + 10px))"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/min-inline-size-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/min-inline-size-invalid.html new file mode 100644 index 0000000..eb2cc8b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/min-inline-size-invalid.html
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing min-inline-size with invalid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical-1/#dimension-properties"> +<meta name="assert" content="min-inline-size supports the full grammar 'auto | <length-percentage> | min-content | max-content | fit-content(<length-percentage>)'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_invalid_value("min-inline-size", "none"); + +test_invalid_value("min-inline-size", "min-content available"); +test_invalid_value("min-inline-size", "max-content 10px"); +test_invalid_value("min-inline-size", "20% available"); + +test_invalid_value("min-inline-size", "-10px"); +test_invalid_value("min-inline-size", "-20%"); +test_invalid_value("min-inline-size", "60"); +test_invalid_value("min-inline-size", "10px 20%"); + +test_invalid_value("min-inline-size", "10px border-box"); +test_invalid_value("min-inline-size", "content-box 20%"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/min-inline-size-valid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/min-inline-size-valid.html new file mode 100644 index 0000000..fa4ba0d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/min-inline-size-valid.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing min-inline-size with valid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical-1/#dimension-properties"> +<meta name="assert" content="min-inline-size supports the full grammar 'auto | <length-percentage> | min-content | max-content | fit-content(<length-percentage>)'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_valid_value("min-inline-size", "auto"); + +test_valid_value("min-inline-size", "10px"); +test_valid_value("min-inline-size", "20%"); +test_valid_value("min-inline-size", "calc(2em + 3ex)"); + +test_valid_value("min-inline-size", "min-content"); +test_valid_value("min-inline-size", "max-content"); + +// The following are not yet supported by browsers: +// test_valid_value("min-inline-size", "fit-content(100px)"); +// test_valid_value("min-inline-size", "fit-content(calc(10% + 10px))"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/interpolation.html b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/interpolation.html new file mode 100644 index 0000000..da3981f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/interpolation.html
@@ -0,0 +1,60 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="assert" + content="This test checks if the inerpolation on clip-path is correct" /> +<title>Tests for the output of the interpolation of clip-path</title> +<link rel="help" href="https://drafts.fxtf.org/css-masking-1/#the-clip-path"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<div id='log'></div> +<script type='text/javascript'> +'use strict'; + +function createDiv(test) { + var element = document.createElement('div'); + document.body.appendChild(element); + test.add_cleanup(function() { + element.remove(); + }); + return element; +} + +test(function(t) { + var div = createDiv(t); + div.style.clipPath = 'circle(25px)'; + // The radius becomes negative between 60%~61%, so we set the delay to -61s. + div.style.transition = 'all 100s cubic-bezier(0, 0, 1, -60) -61s'; + getComputedStyle(div).clipPath; + + div.style.clipPath = 'circle(26px)'; + assert_equals(getComputedStyle(div).clipPath, 'circle(0px at 50% 50%)', + 'The radius of circle is clamped to zero at 61%'); +}, 'Test circle with negative easing on clip-path'); + +test(function(t) { + var div = createDiv(t); + div.style.clipPath = 'ellipse(25px 25px)'; + // The radius becomes negative between 60%~61%, so we set the delay to -61s. + div.style.transition = 'all 100s cubic-bezier(0, 0, 1, -60) -61s'; + getComputedStyle(div).clipPath; + + div.style.clipPath = 'ellipse(26px 26px)'; + assert_equals(getComputedStyle(div).clipPath, 'ellipse(0px 0px at 50% 50%)', + 'The radius of ellipse is clamped to zero at 61%'); +}, 'Test ellipse with negative easing on clip-path'); + +test(function(t) { + var div = createDiv(t); + div.style.clipPath = 'inset(10% round 25px)'; + // The radius becomes negative between 60%~61%, so we set the delay to -61s. + div.style.transition = 'all 100s cubic-bezier(0, 0, 1, -60) -61s'; + getComputedStyle(div).clipPath; + + div.style.clipPath = 'inset(10% round 26px)'; + assert_equals(getComputedStyle(div).clipPath, 'inset(10%)', + 'The radius of inset is clamped to zero at 61%'); +}, 'Test inset with negative easing on clip-path'); + +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-shapes/basic-shape-interpolation.html b/third_party/blink/web_tests/external/wpt/css/css-shapes/basic-shape-interpolation.html new file mode 100644 index 0000000..beea230 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-shapes/basic-shape-interpolation.html
@@ -0,0 +1,62 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="assert" + content="This test checks the inerpolation on basic-shapes is correct" /> +<title>Tests for the output of the interpolation of basic-shapes</title> +<link rel="help" + href="https://drafts.csswg.org/css-shapes/#basic-shape-interpolation"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<div id='log'></div> +<script type='text/javascript'> +'use strict'; + +function createDiv(test) { + var element = document.createElement('div'); + document.body.appendChild(element); + test.add_cleanup(function() { + element.remove(); + }); + return element; +} + +test(function(t) { + var div = createDiv(t); + div.style.shapeOutside = 'circle(25px)'; + // The radius becomes negative between 60%~61%, so we set the delay to -61s. + div.style.transition = 'all 100s cubic-bezier(0, 0, 1, -60) -61s'; + getComputedStyle(div).shapeOutside; + + div.style.shapeOutside = 'circle(26px)'; + assert_equals(getComputedStyle(div).shapeOutside, 'circle(0px at 50% 50%)', + 'The radius of circle is clamped to zero at 61%'); +}, 'Test circle with negative easing on shape-outside'); + +test(function(t) { + var div = createDiv(t); + div.style.shapeOutside = 'ellipse(25px 25px)'; + // The radius becomes negative between 60%~61%, so we set the delay to -61s. + div.style.transition = 'all 100s cubic-bezier(0, 0, 1, -60) -61s'; + getComputedStyle(div).shapeOutside; + + div.style.shapeOutside = 'ellipse(26px 26px)'; + assert_equals(getComputedStyle(div).shapeOutside, + 'ellipse(0px 0px at 50% 50%)', + 'The radius of ellipse is clamped to zero at 61%'); +}, 'Test ellipse with negative easing on shape-outside'); + +test(function(t) { + var div = createDiv(t); + div.style.shapeOutside = 'inset(10% round 25px)'; + // The radius becomes negative between 60%~61%, so we set the delay to -61s. + div.style.transition = 'all 100s cubic-bezier(0, 0, 1, -60) -61s'; + getComputedStyle(div).shapeOutside; + + div.style.shapeOutside = 'inset(10% round 26px)'; + assert_equals(getComputedStyle(div).shapeOutside, 'inset(10%)', + 'The radius of inset is clamped to zero at 61%'); +}, 'Test inset with negative easing on shape-outside'); + +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/filter-subregion-01-ref.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/filter-subregion-01-ref.html new file mode 100644 index 0000000..a91e1fa --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/filter-subregion-01-ref.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>filter primitive subregion: Clip to filter primitive subregion</title> +<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org"> +<p>Test passes if two semi-transparent green rectangles are on top of the +blue boxes to the left, and one opaque green rectangle on the blue box +to the right.</p> +<!-- this is example filtersubregion00 from the specification --> +<img src="support/filtersubregion00.png" style="width:400px; height: 400px"/>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/filter-subregion-01.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/filter-subregion-01.html new file mode 100644 index 0000000..08c8367 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/filter-subregion-01.html
@@ -0,0 +1,53 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>filter primitive subregion: Clip to filter primitive subregion</title> +<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#FilterPrimitiveSubRegion"> +<link rel="match" href="filter-subregion-01-ref.html"> +<p>Test passes if two semi-transparent green rectangles are on top of the +blue boxes to the left, and one opaque green rectangle on the blue box +to the right.</p> +<!-- this is example filtersubregion00.svg from the specification --> +<svg width="400" height="400"> + <defs> + <filter id="flood" x="0" y="0" width="100%" height="100%" primitiveUnits="objectBoundingBox"> + <feFlood x="25%" y="25%" width="50%" height="50%" + flood-color="green" flood-opacity="0.75"/> + </filter> + <filter id="blend" primitiveUnits="objectBoundingBox"> + <feBlend x="25%" y="25%" width="50%" height="50%" + in2="SourceGraphic" mode="multiply"/> + </filter> + <filter id="merge" primitiveUnits="objectBoundingBox"> + <feMerge x="25%" y="25%" width="50%" height="50%"> + <feMergeNode in="SourceGraphic"/> + <feMergeNode in="FillPaint"/> + </feMerge> + </filter> + </defs> + + <g fill="none" stroke="blue" stroke-width="4"> + <rect width="200" height="200"/> + <line x2="200" y2="200"/> + <line x1="200" y2="200"/> + </g> + <circle fill="green" filter="url(#flood)" cx="100" cy="100" r="90"/> + + <g transform="translate(200 0)"> + <g fill="none" stroke="blue" stroke-width="4"> + <rect width="200" height="200"/> + <line x2="200" y2="200"/> + <line x1="200" y2="200"/> + </g> + <circle fill="green" filter="url(#blend)" cx="100" cy="100" r="90"/> + </g> + + <g transform="translate(0 200)"> + <g fill="none" stroke="blue" stroke-width="4"> + <rect width="200" height="200"/> + <line x2="200" y2="200"/> + <line x1="200" y2="200"/> + </g> + <circle fill="green" fill-opacity="0.5" filter="url(#merge)" cx="100" cy="100" r="90"/> + </g> +</svg> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/support/filtersubregion00.png b/third_party/blink/web_tests/external/wpt/css/filter-effects/support/filtersubregion00.png new file mode 100644 index 0000000..b6c4bcc --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/support/filtersubregion00.png Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/idlharness.window-expected.txt b/third_party/blink/web_tests/external/wpt/feature-policy/idlharness.window-expected.txt index 71a041e..43914ea6 100644 --- a/third_party/blink/web_tests/external/wpt/feature-policy/idlharness.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/feature-policy/idlharness.window-expected.txt
@@ -2,12 +2,13 @@ PASS idl_test setup PASS Partial interface Document: original interface defined PASS Partial interface HTMLIFrameElement: original interface defined -PASS Stringification of document.policy -PASS Policy interface: document.policy must inherit property "allowsFeature(DOMString, DOMString)" with the proper type -PASS Policy interface: calling allowsFeature(DOMString, DOMString) on document.policy with too few arguments must throw TypeError -PASS Policy interface: document.policy must inherit property "allowedFeatures()" with the proper type -PASS Policy interface: document.policy must inherit property "getAllowlistForFeature(DOMString)" with the proper type -PASS Policy interface: calling getAllowlistForFeature(DOMString) on document.policy with too few arguments must throw TypeError +FAIL Stringification of document.featurePolicy assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL FeaturePolicy interface: document.featurePolicy must inherit property "allowsFeature(DOMString, DOMString)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL FeaturePolicy interface: calling allowsFeature(DOMString, DOMString) on document.featurePolicy with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL FeaturePolicy interface: document.featurePolicy must inherit property "features()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL FeaturePolicy interface: document.featurePolicy must inherit property "allowedFeatures()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL FeaturePolicy interface: document.featurePolicy must inherit property "getAllowlistForFeature(DOMString)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined" +FAIL FeaturePolicy interface: calling getAllowlistForFeature(DOMString) on document.featurePolicy with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined" FAIL FeaturePolicyViolationReportBody interface: existence and properties of interface object assert_own_property: self does not have own property "FeaturePolicyViolationReportBody" expected property "FeaturePolicyViolationReportBody" missing FAIL FeaturePolicyViolationReportBody interface object length assert_own_property: self does not have own property "FeaturePolicyViolationReportBody" expected property "FeaturePolicyViolationReportBody" missing FAIL FeaturePolicyViolationReportBody interface object name assert_own_property: self does not have own property "FeaturePolicyViolationReportBody" expected property "FeaturePolicyViolationReportBody" missing @@ -19,8 +20,8 @@ FAIL FeaturePolicyViolationReportBody interface: attribute lineNumber assert_own_property: self does not have own property "FeaturePolicyViolationReportBody" expected property "FeaturePolicyViolationReportBody" missing FAIL FeaturePolicyViolationReportBody interface: attribute columnNumber assert_own_property: self does not have own property "FeaturePolicyViolationReportBody" expected property "FeaturePolicyViolationReportBody" missing FAIL FeaturePolicyViolationReportBody interface: attribute disposition assert_own_property: self does not have own property "FeaturePolicyViolationReportBody" expected property "FeaturePolicyViolationReportBody" missing -PASS HTMLIFrameElement interface: attribute policy -PASS Document interface: attribute policy -PASS Document interface: document must inherit property "policy" with the proper type +FAIL HTMLIFrameElement interface: attribute featurePolicy assert_true: The prototype object must have a property "featurePolicy" expected true got false +FAIL Document interface: attribute featurePolicy assert_true: The prototype object must have a property "featurePolicy" expected true got false +FAIL Document interface: document must inherit property "featurePolicy" with the proper type assert_inherits: property "featurePolicy" not found in prototype chain Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/idlharness.window.js b/third_party/blink/web_tests/external/wpt/feature-policy/idlharness.window.js index fb17cab9..33bbe3c 100644 --- a/third_party/blink/web_tests/external/wpt/feature-policy/idlharness.window.js +++ b/third_party/blink/web_tests/external/wpt/feature-policy/idlharness.window.js
@@ -12,7 +12,7 @@ idl_array.add_objects({ Document: ['document'], HTMLIframeElement: ['document.createElement("iframe")'], - Policy: ['document.policy'], + FeaturePolicy: ['document.featurePolicy'], }) } );
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_javascript_url_01.htm b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_javascript_url_01.htm index d6c2abe7..fd65f93 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_javascript_url_01.htm +++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_javascript_url_01.htm
@@ -18,7 +18,8 @@ ifr1:{url:"about:blank", sameDom: true}, ifr2:{url:"about:blank", sameDom: true}, ifr3:{url: location.href.replace(/\/[^\/]*$/, '/'), sameDom: true }, - ifr4:{url:"about:blank", sameDom: true} + ifr4:{url:"about:blank", sameDom: true}, + ifr5:{url:"about:blank", sameDom: true} } var js_url = 'javascript:"<html><script>var sameDom = false; try{var cn = top.document.body.className;sameDom = true;}catch(e){}; parent.postMessage( {url: document.URL, name: name, sameDom: sameDom}, \'*\')<\/script><body><p>JS-generated document</p></body></<html>";' @@ -46,8 +47,15 @@ results[frame.name] = 'Exception on setting!'; } }; + + // An iframe with an initial src of a javascript: URL should also have a + // document URL of about:blank. + var ifr = document.createElement('iframe'); + ifr.name = 'ifr5'; + ifr.src = js_url; + document.body.appendChild(ifr); } </script> </body> -</html> \ No newline at end of file +</html>
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/elementTiming.html.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/elementTiming.html.ini new file mode 100644 index 0000000..a06134a6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/elementTiming.html.ini
@@ -0,0 +1,4 @@ +[elementTiming.html] + [TestDriver actions: element timing] + expected: + if product == "chrome": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/eventOrder.html.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/eventOrder.html.ini index 07c05be..00916c7a 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/eventOrder.html.ini +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/eventOrder.html.ini
@@ -1,3 +1,7 @@ [eventOrder.html] expected: - if product == "safari": ERROR \ No newline at end of file + if product == "safari": ERROR + + [TestDriver actions: event order] + expected: + if product == "chrome": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/multiDevice.html.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/multiDevice.html.ini index 04b97a7..b9fb259 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/multiDevice.html.ini +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/actions/multiDevice.html.ini
@@ -1,3 +1,3 @@ [multiDevice.html] expected: - if product == "safari": ERROR + if product == "chrome" or product == "safari": ERROR
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/feature-policy.idl b/third_party/blink/web_tests/external/wpt/interfaces/feature-policy.idl index c09cc33..2a04215 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/feature-policy.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/feature-policy.idl
@@ -4,18 +4,19 @@ // Source: Feature Policy (https://wicg.github.io/feature-policy/) [NoInterfaceObject] -interface Policy { +interface FeaturePolicy { boolean allowsFeature(DOMString feature, optional DOMString origin); + sequence<DOMString> features(); sequence<DOMString> allowedFeatures(); sequence<DOMString> getAllowlistForFeature(DOMString feature); }; partial interface Document { - [SameObject] readonly attribute Policy policy; + [SameObject] readonly attribute FeaturePolicy featurePolicy; }; partial interface HTMLIFrameElement { - [SameObject] readonly attribute Policy policy; + [SameObject] readonly attribute FeaturePolicy featurePolicy; }; interface FeaturePolicyViolationReportBody : ReportBody { readonly attribute DOMString featureId;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/shape-detection-api.idl b/third_party/blink/web_tests/external/wpt/interfaces/shape-detection-api.idl index dbdf022e..66c5889 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/shape-detection-api.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/shape-detection-api.idl
@@ -14,6 +14,7 @@ boolean fastMode; }; +[Serializable] interface DetectedFace { [SameObject] readonly attribute DOMRectReadOnly boundingBox; [SameObject] readonly attribute FrozenArray<Landmark>? landmarks; @@ -42,6 +43,7 @@ sequence<BarcodeFormat> formats; }; +[Serializable] interface DetectedBarcode { [SameObject] readonly attribute DOMRectReadOnly boundingBox; [SameObject] readonly attribute DOMString rawValue;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/wai-aria.idl b/third_party/blink/web_tests/external/wpt/interfaces/wai-aria.idl index c6ea959..21feb78b 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/wai-aria.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/wai-aria.idl
@@ -1,7 +1,7 @@ // GENERATED CONTENT - DO NOT EDIT // Content was automatically extracted by Reffy into reffy-reports // (https://github.com/tidoust/reffy-reports) -// Source: Accessible Rich Internet Applications (WAI-ARIA) 1.2 (https://w3c.github.io/aria/) +// Source: Accessible Rich Internet Applications (WAI-ARIA) 1.2 (https://rawgit.com/w3c/aria/master/) interface mixin AccessibilityRole { attribute DOMString? role;
diff --git a/third_party/blink/web_tests/external/wpt/resources/testharness.js b/third_party/blink/web_tests/external/wpt/resources/testharness.js index b08074b9..b53ceaf 100644 --- a/third_party/blink/web_tests/external/wpt/resources/testharness.js +++ b/third_party/blink/web_tests/external/wpt/resources/testharness.js
@@ -513,7 +513,7 @@ return new DedicatedWorkerTestEnvironment(); } - if (!('self' in global_scope)) { + if (!('location' in global_scope)) { return new ShellTestEnvironment(); }
diff --git a/third_party/blink/web_tests/external/wpt/streams/byte-length-queuing-strategy.any.js b/third_party/blink/web_tests/external/wpt/streams/byte-length-queuing-strategy.any.js index e4ad144..d47e7cd 100644 --- a/third_party/blink/web_tests/external/wpt/streams/byte-length-queuing-strategy.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/byte-length-queuing-strategy.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict'; test(() => {
diff --git a/third_party/blink/web_tests/external/wpt/streams/count-queuing-strategy.any.js b/third_party/blink/web_tests/external/wpt/streams/count-queuing-strategy.any.js index 00cba3c..20bb4c1 100644 --- a/third_party/blink/web_tests/external/wpt/streams/count-queuing-strategy.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/count-queuing-strategy.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict'; test(() => {
diff --git a/third_party/blink/web_tests/external/wpt/streams/piping/abort.any.js b/third_party/blink/web_tests/external/wpt/streams/piping/abort.any.js index 6282a15..5064533d 100644 --- a/third_party/blink/web_tests/external/wpt/streams/piping/abort.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/piping/abort.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/recording-streams.js // META: script=../resources/test-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/piping/close-propagation-backward.any.js b/third_party/blink/web_tests/external/wpt/streams/piping/close-propagation-backward.any.js index 90f64126..99141e3 100644 --- a/third_party/blink/web_tests/external/wpt/streams/piping/close-propagation-backward.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/piping/close-propagation-backward.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/recording-streams.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/piping/close-propagation-forward.any.js b/third_party/blink/web_tests/external/wpt/streams/piping/close-propagation-forward.any.js index da24971..8851348 100644 --- a/third_party/blink/web_tests/external/wpt/streams/piping/close-propagation-forward.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/piping/close-propagation-forward.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/piping/error-propagation-backward.any.js b/third_party/blink/web_tests/external/wpt/streams/piping/error-propagation-backward.any.js index c822b80..da92e8e 100644 --- a/third_party/blink/web_tests/external/wpt/streams/piping/error-propagation-backward.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/piping/error-propagation-backward.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/piping/error-propagation-forward.any.js b/third_party/blink/web_tests/external/wpt/streams/piping/error-propagation-forward.any.js index b04bf88..113422e 100644 --- a/third_party/blink/web_tests/external/wpt/streams/piping/error-propagation-forward.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/piping/error-propagation-forward.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/piping/flow-control.any.js b/third_party/blink/web_tests/external/wpt/streams/piping/flow-control.any.js index ff1f81c0..05762a42 100644 --- a/third_party/blink/web_tests/external/wpt/streams/piping/flow-control.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/piping/flow-control.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js // META: script=../resources/rs-utils.js // META: script=../resources/recording-streams.js
diff --git a/third_party/blink/web_tests/external/wpt/streams/piping/general.any.js b/third_party/blink/web_tests/external/wpt/streams/piping/general.any.js index 9ba4945..250ebc3 100644 --- a/third_party/blink/web_tests/external/wpt/streams/piping/general.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/piping/general.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/piping/multiple-propagation.any.js b/third_party/blink/web_tests/external/wpt/streams/piping/multiple-propagation.any.js index cd7cd5a..541cfad 100644 --- a/third_party/blink/web_tests/external/wpt/streams/piping/multiple-propagation.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/piping/multiple-propagation.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/piping/pipe-through.any.js b/third_party/blink/web_tests/external/wpt/streams/piping/pipe-through.any.js index 2b896f5..868899c7 100644 --- a/third_party/blink/web_tests/external/wpt/streams/piping/pipe-through.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/piping/pipe-through.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/rs-utils.js // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js
diff --git a/third_party/blink/web_tests/external/wpt/streams/piping/then-interception.any.js b/third_party/blink/web_tests/external/wpt/streams/piping/then-interception.any.js index ef0b824..3c85f6e 100644 --- a/third_party/blink/web_tests/external/wpt/streams/piping/then-interception.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/piping/then-interception.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/piping/transform-streams.any.js b/third_party/blink/web_tests/external/wpt/streams/piping/transform-streams.any.js index 8cb34292..368ed79d 100644 --- a/third_party/blink/web_tests/external/wpt/streams/piping/transform-streams.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/piping/transform-streams.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict'; promise_test(() => {
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/brand-checks.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/brand-checks.any.js index 62f5127..e4d5e26 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/brand-checks.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/brand-checks.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.js index 427166f6..428cdeb7 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/rs-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/constructor.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/constructor.any.js index 4033ad46..b950e05 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/constructor.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/constructor.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/constructor-ordering.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/detached-buffers.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/detached-buffers.any.js index bf1d5c7..7d87173 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/detached-buffers.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/detached-buffers.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict'; promise_test(() => {
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/general.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/general.any.js index 11a627d7..c8f1fb78 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/general.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/general.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/rs-utils.js // META: script=../resources/test-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/properties.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/properties.any.js index 255089c2..2d52fd67 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/properties.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/properties.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/rs-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-streams/bad-strategies.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-streams/bad-strategies.any.js index 9582b29..5dab51e 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-streams/bad-strategies.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-streams/bad-strategies.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict'; test(() => {
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-streams/bad-underlying-sources.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-streams/bad-underlying-sources.any.js index aee2e82..cde5603 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-streams/bad-underlying-sources.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-streams/bad-underlying-sources.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-streams/brand-checks.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-streams/brand-checks.any.js index 6c2987a..2906494b 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-streams/brand-checks.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-streams/brand-checks.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-streams/cancel.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-streams/cancel.any.js index b384283..75bd9c7 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-streams/cancel.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-streams/cancel.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js // META: script=../resources/rs-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-streams/constructor.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-streams/constructor.any.js index 3a66472e..e0f5edd0 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-streams/constructor.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-streams/constructor.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/constructor-ordering.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-streams/count-queuing-strategy-integration.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-streams/count-queuing-strategy-integration.any.js index 45959cb..a60e70d 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-streams/count-queuing-strategy-integration.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-streams/count-queuing-strategy-integration.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict'; test(() => {
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-streams/default-reader.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-streams/default-reader.any.js index 3fde392..7c13b15 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-streams/default-reader.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-streams/default-reader.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/rs-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-streams/floating-point-total-queue-size.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-streams/floating-point-total-queue-size.any.js index 038258c5f..9e4e54c 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-streams/floating-point-total-queue-size.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-streams/floating-point-total-queue-size.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict'; // Due to the limitations of floating-point precision, the calculation of desiredSize sometimes gives different answers
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-streams/garbage-collection.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-streams/garbage-collection.any.js index c3353acf..b6f2a7f 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-streams/garbage-collection.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-streams/garbage-collection.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-streams/general.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-streams/general.any.js index 5e8a4af..f885ed6d 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-streams/general.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-streams/general.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js // META: script=../resources/rs-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-streams/patched-global.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-streams/patched-global.any.js index b3d5a3364..fa49249a 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-streams/patched-global.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-streams/patched-global.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict'; // Tests which patch the global environment are kept separate to avoid
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-streams/reentrant-strategies.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-streams/reentrant-strategies.any.js index 05471ce..7724ea63 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-streams/reentrant-strategies.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-streams/reentrant-strategies.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/recording-streams.js // META: script=../resources/rs-utils.js // META: script=../resources/test-utils.js
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any.js index 1b25ca7f..a06e249 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-streams/tee.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/rs-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-streams/templated.any.js b/third_party/blink/web_tests/external/wpt/streams/readable-streams/templated.any.js index 5926c08..b5cc0b30 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-streams/templated.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/readable-streams/templated.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js // META: script=../resources/rs-test-templates.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/transform-streams/backpressure.any.js b/third_party/blink/web_tests/external/wpt/streams/transform-streams/backpressure.any.js index 44d91b7f..a604096 100644 --- a/third_party/blink/web_tests/external/wpt/streams/transform-streams/backpressure.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/transform-streams/backpressure.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/recording-streams.js // META: script=../resources/test-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/transform-streams/brand-checks.any.js b/third_party/blink/web_tests/external/wpt/streams/transform-streams/brand-checks.any.js index 2fbcd039c..79a5d55 100644 --- a/third_party/blink/web_tests/external/wpt/streams/transform-streams/brand-checks.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/transform-streams/brand-checks.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/transform-streams/constructor.any.js b/third_party/blink/web_tests/external/wpt/streams/transform-streams/constructor.any.js index 69e9be3..dfa966e0 100644 --- a/third_party/blink/web_tests/external/wpt/streams/transform-streams/constructor.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/transform-streams/constructor.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/constructor-ordering.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/transform-streams/errors.any.js b/third_party/blink/web_tests/external/wpt/streams/transform-streams/errors.any.js index a0a8e204..53a4a49 100644 --- a/third_party/blink/web_tests/external/wpt/streams/transform-streams/errors.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/transform-streams/errors.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/transform-streams/flush.any.js b/third_party/blink/web_tests/external/wpt/streams/transform-streams/flush.any.js index df0cc96..ef08967 100644 --- a/third_party/blink/web_tests/external/wpt/streams/transform-streams/flush.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/transform-streams/flush.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/transform-streams/general.any.js b/third_party/blink/web_tests/external/wpt/streams/transform-streams/general.any.js index 0b012a9..537001e 100644 --- a/third_party/blink/web_tests/external/wpt/streams/transform-streams/general.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/transform-streams/general.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js // META: script=../resources/rs-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/transform-streams/lipfuzz.any.js b/third_party/blink/web_tests/external/wpt/streams/transform-streams/lipfuzz.any.js index a5f09ee2..c31d0e46 100644 --- a/third_party/blink/web_tests/external/wpt/streams/transform-streams/lipfuzz.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/transform-streams/lipfuzz.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict'; class LipFuzzTransformer {
diff --git a/third_party/blink/web_tests/external/wpt/streams/transform-streams/patched-global.any.js b/third_party/blink/web_tests/external/wpt/streams/transform-streams/patched-global.any.js index 34a602e..52d44a3 100644 --- a/third_party/blink/web_tests/external/wpt/streams/transform-streams/patched-global.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/transform-streams/patched-global.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict'; // Tests which patch the global environment are kept separate to avoid interfering with other tests.
diff --git a/third_party/blink/web_tests/external/wpt/streams/transform-streams/properties.any.js b/third_party/blink/web_tests/external/wpt/streams/transform-streams/properties.any.js index 3208cfe..892d66169 100644 --- a/third_party/blink/web_tests/external/wpt/streams/transform-streams/properties.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/transform-streams/properties.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict'; // The purpose of this file is to test for objects, attributes and arguments that should not exist.
diff --git a/third_party/blink/web_tests/external/wpt/streams/transform-streams/reentrant-strategies.any.js b/third_party/blink/web_tests/external/wpt/streams/transform-streams/reentrant-strategies.any.js index d9e2937..c18d6d10 100644 --- a/third_party/blink/web_tests/external/wpt/streams/transform-streams/reentrant-strategies.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/transform-streams/reentrant-strategies.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/recording-streams.js // META: script=../resources/rs-utils.js // META: script=../resources/test-utils.js
diff --git a/third_party/blink/web_tests/external/wpt/streams/transform-streams/strategies.any.js b/third_party/blink/web_tests/external/wpt/streams/transform-streams/strategies.any.js index 894d1fa8..9ebfec7 100644 --- a/third_party/blink/web_tests/external/wpt/streams/transform-streams/strategies.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/transform-streams/strategies.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/recording-streams.js // META: script=../resources/test-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/transform-streams/terminate.any.js b/third_party/blink/web_tests/external/wpt/streams/transform-streams/terminate.any.js index 231adbd..2bf9eab 100644 --- a/third_party/blink/web_tests/external/wpt/streams/transform-streams/terminate.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/transform-streams/terminate.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/recording-streams.js // META: script=../resources/test-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any.js b/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any.js index 10753fe..18fb58e 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/bad-strategies.any.js b/third_party/blink/web_tests/external/wpt/streams/writable-streams/bad-strategies.any.js index 5832d45..d67ee6b5 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/bad-strategies.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/bad-strategies.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict'; const error1 = new Error('a unique string');
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/bad-underlying-sinks.any.js b/third_party/blink/web_tests/external/wpt/streams/writable-streams/bad-underlying-sinks.any.js index e523c46..ed04b3c 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/bad-underlying-sinks.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/bad-underlying-sinks.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/brand-checks.any.js b/third_party/blink/web_tests/external/wpt/streams/writable-streams/brand-checks.any.js index 06e75cc..968cb4c 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/brand-checks.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/brand-checks.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/byte-length-queuing-strategy.any.js b/third_party/blink/web_tests/external/wpt/streams/writable-streams/byte-length-queuing-strategy.any.js index 3c8c8bf..5edd41c 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/byte-length-queuing-strategy.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/byte-length-queuing-strategy.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict'; promise_test(t => {
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/close.any.js b/third_party/blink/web_tests/external/wpt/streams/writable-streams/close.any.js index 79f1b03e..21f361f 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/close.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/close.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/constructor.any.js b/third_party/blink/web_tests/external/wpt/streams/writable-streams/constructor.any.js index 9379910..97cda9ce 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/constructor.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/constructor.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/constructor-ordering.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/count-queuing-strategy.any.js b/third_party/blink/web_tests/external/wpt/streams/writable-streams/count-queuing-strategy.any.js index f48ec8db..e8d9ca8 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/count-queuing-strategy.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/count-queuing-strategy.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict'; test(() => {
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/error.any.js b/third_party/blink/web_tests/external/wpt/streams/writable-streams/error.any.js index e0a87a6..76b5c8a 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/error.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/error.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict'; const error1 = new Error('error1');
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/floating-point-total-queue-size.any.js b/third_party/blink/web_tests/external/wpt/streams/writable-streams/floating-point-total-queue-size.any.js index a06f4a12..580c8cb 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/floating-point-total-queue-size.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/floating-point-total-queue-size.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict'; // Due to the limitations of floating-point precision, the calculation of desiredSize sometimes gives different answers
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/general.any.js b/third_party/blink/web_tests/external/wpt/streams/writable-streams/general.any.js index 6ddae1f..253909f2 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/general.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/general.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict'; test(() => {
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any.js b/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any.js index fe798a7..b991795a 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/properties.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell 'use strict'; // The purpose of this file is to test for objects, attributes and arguments that should not exist.
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/reentrant-strategy.any.js b/third_party/blink/web_tests/external/wpt/streams/writable-streams/reentrant-strategy.any.js index c8c5937..8fa31f9d1 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/reentrant-strategy.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/reentrant-strategy.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/start.any.js b/third_party/blink/web_tests/external/wpt/streams/writable-streams/start.any.js index 69cc131..0a1095b 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/start.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/start.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/write.any.js b/third_party/blink/web_tests/external/wpt/streams/writable-streams/write.any.js index 19299f01..85c7f8c 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/write.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/write.any.js
@@ -1,4 +1,4 @@ -// META: global=worker +// META: global=worker,jsshell // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict';
diff --git a/third_party/blink/web_tests/external/wpt/svg/geometry/parsing/sizing-properties-computed.svg b/third_party/blink/web_tests/external/wpt/svg/geometry/parsing/sizing-properties-computed.svg new file mode 100644 index 0000000..93d6815 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/geometry/parsing/sizing-properties-computed.svg
@@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:h="http://www.w3.org/1999/xhtml" + width="800px" height="800px"> + <title>SVG Geometry Properties: getComputedValue().width</title> + <metadata> + <h:link rel="help" href="https://svgwg.org/svg2-draft/geometry.html#Sizing"/> + <h:link rel="help" href="https://drafts.csswg.org/css-sizing-3/#preferred-size-properties"/> + <h:link rel="help" href="https://drafts.csswg.org/cssom/#resolved-values"/> + </metadata> + <rect id="target"></rect> + <style> + #target { + font-size: 40px; + } + </style> + <h:script src="/resources/testharness.js"/> + <h:script src="/resources/testharnessreport.js"/> + <h:script src="/css/support/computed-testcommon.js"/> + <script><![CDATA[ + +test_computed_value("width", "10px"); +test_computed_value("width", "0.5em", "20px"); +test_computed_value("width", "calc(10px + 0.5em)", "30px"); +test_computed_value("width", "calc(10px - 0.5em)", "0px"); +test_computed_value("width", "40%", "320px"); +test_computed_value("width", "calc(50% + 1.5em)", "460px"); + +test_computed_value("height", "10px"); +test_computed_value("height", "0.5em", "20px"); +test_computed_value("height", "calc(10px + 0.5em)", "30px"); +test_computed_value("height", "calc(10px - 0.5em)", "0px"); +test_computed_value("height", "40%", "320px"); +test_computed_value("height", "calc(50% + 1.5em)", "460px"); + +test(() => { + const target = document.getElementById('target'); + target.style.width = 'calc(50% + 1.5em)'; + target.style.display = 'none'; + assert_equals(getComputedStyle(target).width, 'calc(50% + 60px)'); + target.style.width = ''; + target.style.display = ''; +}, "resolved value is computed value when display is none"); + +test(() => { + const target = document.getElementById('target'); + target.style.height = 'calc(50% + 1.5em)'; + target.style.display = 'none'; + assert_equals(getComputedStyle(target).height, 'calc(50% + 60px)'); + target.style.height = ''; + target.style.display = ''; +}, "resolved value is computed value when display is contents"); + + ]]></script> +} +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCTrackEvent-fire.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCTrackEvent-fire.html new file mode 100644 index 0000000..2e226c3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCTrackEvent-fire.html
@@ -0,0 +1,80 @@ +<!doctype html> +<meta charset=utf-8> +<title>Change of msid in remote description should trigger related track events</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +const sdpBase =`v=0 +o=- 5511237691691746 2 IN IP4 127.0.0.1 +s=- +t=0 0 +a=group:BUNDLE 0 +a=ice-options:trickle +a=ice-lite +a=msid-semantic:WMS * +m=audio 9 UDP/TLS/RTP/SAVPF 111 103 9 102 0 8 105 13 110 113 126 +c=IN IP6 :: +a=rtcp:9 IN IP6 :: +a=rtcp-mux +a=mid:0 +a=sendrecv +a=ice-ufrag:z0i8R3C9C4hPRWls +a=ice-pwd:O7bPpOFAqasqoidV4yxnFVbc +a=ice-lite +a=fingerprint:sha-256 B7:9C:0D:C9:D1:42:57:97:82:4D:F9:B7:93:75:49:C3:42:21:5A:DD:9C:B5:ED:53:53:F0:B4:C8:AE:88:7A:E7 +a=setup:actpass +a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level +a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid +a=rtpmap:0 PCMU/8000`; + +const sdp0 = sdpBase + ` +`; + +const sdp1 = sdpBase + ` +a=msid:1 2 +a=ssrc:3 cname:4 +a=ssrc:3 msid:1 2 +`; + +async function applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp) +{ + const testTrackPromise = new Promise(resolve => { + pc.ontrack = (event) => { resolve([event.track, event.streams]); }; + }); + await pc.setRemoteDescription({type: 'offer', sdp: sdp}); + return testTrackPromise; +} + +promise_test(async test => { + const pc = new RTCPeerConnection(); + test.add_cleanup(() => pc.close()); + + const [track, streams] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp1); + assert_equals(streams.length, 1, "track event has a stream"); + assert_equals(streams[0].id, "1", "msid should match"); + const stream = streams[0]; + + await pc.setLocalDescription(await pc.createAnswer()); + + const testTrackPromise = new Promise((resolve) => { stream.onremovetrack = resolve; }); + await pc.setRemoteDescription({type: 'offer', 'sdp': sdp0}); + await testTrackPromise; + + assert_equals(stream.getAudioTracks().length, 0, "stream should be empty"); +}, "Applying a remote description with removed msid should trigger firing a removetrack event on the corresponding stream"); + +promise_test(async test => { + const pc = new RTCPeerConnection(); + test.add_cleanup(() => pc.close()); + + let [track0, streams0] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp0); + + await pc.setLocalDescription(await pc.createAnswer()); + + let [track1, streams1] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp1); + + assert_equals(streams1.length, 1, "track event has a stream"); + assert_equals(streams1[0].id, "1", "msid should match"); + assert_equals(streams1[0].getTracks()[0], track0, "track should match"); +}, "Applying a remote description with a new msid should trigger firing an event with populated streams"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/protocol/missing-fields.html b/third_party/blink/web_tests/external/wpt/webrtc/protocol/missing-fields.html new file mode 100644 index 0000000..d5aafd2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webrtc/protocol/missing-fields.html
@@ -0,0 +1,47 @@ +<!doctype html> +<meta charset=utf-8> +<title>RTCPeerconnection SDP parse tests</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../RTCPeerConnection-helper.js"></script> +<script> +'use strict'; + +function removeSdpLines(description, toRemove) { + const edited = description.sdp.split('\n').filter(function(line) { + return (!line.startsWith(toRemove)); + }).join('\n'); + return {type: description.type, sdp: edited}; +} + +promise_test(async t => { + const caller = new RTCPeerConnection(); + const callee = new RTCPeerConnection(); + t.add_cleanup(() => caller.close()); + t.add_cleanup(() => callee.close()); + caller.addTrack(trackFactories.audio()); + const offer = await caller.createOffer(); + await caller.setLocalDescription(offer); + let remote_offer = removeSdpLines(offer, 'a=mid:'); + remote_offer = removeSdpLines(remote_offer, 'a=group:'); + await callee.setRemoteDescription(remote_offer); + const answer = await callee.createAnswer(); + await caller.setRemoteDescription(answer); +}, 'Offer description with no mid is accepted'); + +promise_test(async t => { + const caller = new RTCPeerConnection(); + const callee = new RTCPeerConnection(); + t.add_cleanup(() => caller.close()); + t.add_cleanup(() => callee.close()); + caller.addTrack(trackFactories.audio()); + const offer = await caller.createOffer(); + await caller.setLocalDescription(offer); + await callee.setRemoteDescription(offer); + const answer = await callee.createAnswer(); + let remote_answer = removeSdpLines(answer, 'a=mid:'); + remote_answer = removeSdpLines(remote_answer, 'a=group:'); + await caller.setRemoteDescription(remote_answer); +}, 'Answer description with no mid is accepted'); + +</script>
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt index 35bde7b..4f058d4 100644 --- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt +++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt
@@ -41,6 +41,7 @@ PASS window.cached_navigator.userAgent is '' PASS window.cached_navigator.vendor is window.navigator.vendor PASS window.cached_navigator.vendorSub is '' +PASS window.cached_navigator_bluetooth.onadvertisementreceived is null PASS window.cached_navigator_connection.onchange is null PASS window.cached_navigator_connection.ontypechange is null PASS window.cached_navigator_connection.saveData is false
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt index 56f72c0..14cad64 100644 --- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt +++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
@@ -41,6 +41,7 @@ PASS window.cached_navigator.userAgent is '' PASS window.cached_navigator.vendor is window.navigator.vendor PASS window.cached_navigator.vendorSub is '' +PASS window.cached_navigator_bluetooth.onadvertisementreceived is null PASS window.cached_navigator_connection.onchange is null PASS window.cached_navigator_connection.ontypechange is null PASS window.cached_navigator_connection.saveData is false
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt index 0e46b5e8..f4cc514 100644 --- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt +++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
@@ -41,6 +41,7 @@ PASS window.cached_navigator.userAgent is '' PASS window.cached_navigator.vendor is window.navigator.vendor PASS window.cached_navigator.vendorSub is '' +PASS window.cached_navigator_bluetooth.onadvertisementreceived is null PASS window.cached_navigator_connection.onchange is null PASS window.cached_navigator_connection.ontypechange is null PASS window.cached_navigator_connection.saveData is false
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt index 8afbc7a..c9b062b 100644 --- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt +++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
@@ -37,6 +37,7 @@ PASS oldChildWindow.navigator.appCodeName is newChildWindow.navigator.appCodeName PASS oldChildWindow.navigator.appName is newChildWindow.navigator.appName PASS oldChildWindow.navigator.appVersion is newChildWindow.navigator.appVersion +PASS oldChildWindow.navigator.bluetooth.onadvertisementreceived is newChildWindow.navigator.bluetooth.onadvertisementreceived PASS oldChildWindow.navigator.connection.onchange is newChildWindow.navigator.connection.onchange PASS oldChildWindow.navigator.connection.ontypechange is newChildWindow.navigator.connection.ontypechange PASS oldChildWindow.navigator.connection.saveData is newChildWindow.navigator.connection.saveData
diff --git a/third_party/blink/web_tests/fast/dom/javascript-url-exception-isolation.html b/third_party/blink/web_tests/fast/dom/javascript-url-exception-isolation.html index fb0e0d5..0ad08b2 100644 --- a/third_party/blink/web_tests/fast/dom/javascript-url-exception-isolation.html +++ b/third_party/blink/web_tests/fast/dom/javascript-url-exception-isolation.html
@@ -7,26 +7,44 @@ <script> description("Exceptions thrown in javascript URLs should not propagate to the main script.") +var jsTestIsAsync = true; + var subframe = document.createElement("iframe"); document.body.appendChild(subframe); var caughtException = false; - -// Runtime exception. -try { - subframe.src = 'javascript:throw 42'; -} catch(e) { - caughtException = true; +function test(idx) { + switch (idx) { + case 0: + // Runtime exception. + try { + subframe.src = 'javascript:throw 42'; + } catch(e) { + caughtException = true; + } + shouldBeFalse('caughtException'); + break; + case 1: + // Compile-time exception. + try { + subframe.src = 'javascript:<html></html>'; + } catch(e) { + caughtException = true; + } + shouldBeFalse('caughtException'); + break; + case 2: + finishJSTest(); + return; + } + // Wait for script to evaluate. + setTimeout(() => { + test(idx + 1); + }, 0); } -shouldBeFalse('caughtException'); -// Compile-time exception. -try { - subframe.src = 'javascript:<html></html>'; -} catch(e) { - caughtException = true; -} -shouldBeFalse('caughtException'); +test(0); + </script> </body> </html>
diff --git a/third_party/blink/web_tests/fast/events/javascript-uri-navigation-blocked-in-unload-handler-expected.txt b/third_party/blink/web_tests/fast/events/javascript-uri-navigation-blocked-in-unload-handler-expected.txt index 695552ac..8b13789 100644 --- a/third_party/blink/web_tests/fast/events/javascript-uri-navigation-blocked-in-unload-handler-expected.txt +++ b/third_party/blink/web_tests/fast/events/javascript-uri-navigation-blocked-in-unload-handler-expected.txt
@@ -1,2 +1 @@ -PASS: script executed
diff --git a/third_party/blink/web_tests/fast/events/javascript-uri-navigation-blocked-in-unload-handler.html b/third_party/blink/web_tests/fast/events/javascript-uri-navigation-blocked-in-unload-handler.html index b09105e..4397239 100644 --- a/third_party/blink/web_tests/fast/events/javascript-uri-navigation-blocked-in-unload-handler.html +++ b/third_party/blink/web_tests/fast/events/javascript-uri-navigation-blocked-in-unload-handler.html
@@ -16,11 +16,19 @@ var i = document.body.appendChild(document.createElement('iframe')); i.contentWindow.onunload = function() { - i.src = "javascript:top.log('PASS: script executed');" + - "'<script>top.log(\\'FAIL: document navigation not aborted\\');<" + + // This navigation should be compliant with step 4 of + // https://html.spec.whatwg.org/#navigate. + // "If there is a preexisting attempt to navigate browsingContext, and the + // source browsing context is the same as browsingContext, and that attempt is + // currently running the unload a document algorithm, then return without + // affecting the preexisting attempt to navigate browsingContext." + i.src = "javascript:'<script>top.log(\\'FAIL: document navigation not aborted\\');<" + "/script>'"; - if (window.testRunner) - testRunner.notifyDone(); +} + +i.onload = function() { + if (window.testRunner) + testRunner.notifyDone(); } i.src = "data:text/html,test";
diff --git a/third_party/blink/web_tests/fast/parser/resources/set-parent-to-javascript-url.html b/third_party/blink/web_tests/fast/parser/resources/set-parent-to-javascript-url.html index cae7ee69..d5a8bf5 100644 --- a/third_party/blink/web_tests/fast/parser/resources/set-parent-to-javascript-url.html +++ b/third_party/blink/web_tests/fast/parser/resources/set-parent-to-javascript-url.html
@@ -1,8 +1,7 @@ <script> // Capture window.parent: once this context navigates, window.parent always returns null. -var p = parent; alert(1); -parent.document.getElementsByTagName('iframe')[0].src = "javascript:alert(2),'PASS<script>alert(3)<\/script>'"; -alert(4); -p.setTimeout("done()", 0); +const iframe = parent.document.getElementsByTagName('iframe')[0]; +iframe.src = "javascript:alert(3),'PASS<script>alert(4);parent.window.done()<\/script>'"; +alert(2); </script>
diff --git a/third_party/blink/web_tests/http/tests/devtools/components/cookies-table-expected.txt b/third_party/blink/web_tests/http/tests/devtools/components/cookies-table-expected.txt index 270df13..bd10abc 100644 --- a/third_party/blink/web_tests/http/tests/devtools/components/cookies-table-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/components/cookies-table-expected.txt
@@ -18,57 +18,57 @@ # of node.appendChild calls: 6 # of node.removeChildren calls: 2 -node.appendChild call: cookieA 11 -node.appendChild call: cookieB 2 -node.appendChild call: cookieC foo -node.appendChild call: cookieD {other} -node.appendChild call: cookieE zz -node.appendChild call: cookieF null +node.appendChild call: cookieA 11 Session +node.appendChild call: cookieB 2 1970-01-01T00:00:00.001Z +node.appendChild call: cookieC foo 2018-12-17T14:31:30.000Z +node.appendChild call: cookieD {other} 1970-01-01T05:32:21.213Z +node.appendChild call: cookieE zz 1970-01-01T01:42:01.598Z +node.appendChild call: cookieF null N/A --- Descending selection test --- # of node.appendChild calls: 6 # of node.removeChildren calls: 2 -node.appendChild call: cookieF null -node.appendChild call: cookieE zz -node.appendChild call: cookieD {other} -node.appendChild call: cookieC foo [selected] -node.appendChild call: cookieB 2 -node.appendChild call: cookieA 11 +node.appendChild call: cookieF null N/A +node.appendChild call: cookieE zz 1970-01-01T01:42:01.598Z +node.appendChild call: cookieD {other} 1970-01-01T05:32:21.213Z +node.appendChild call: cookieC foo 2018-12-17T14:31:30.000Z [selected] +node.appendChild call: cookieB 2 1970-01-01T00:00:00.001Z +node.appendChild call: cookieA 11 Session --- Neighbor selection test --- # of node.appendChild calls: 6 # of node.removeChildren calls: 2 -node.appendChild call: cookieA 11 [selected] -node.appendChild call: cookieB 2 -node.appendChild call: cookieC foo -node.appendChild call: cookieD {other} -node.appendChild call: cookieE zz -node.appendChild call: cookieF null +node.appendChild call: cookieA 11 Session [selected] +node.appendChild call: cookieB 2 1970-01-01T00:00:00.001Z +node.appendChild call: cookieC foo 2018-12-17T14:31:30.000Z +node.appendChild call: cookieD {other} 1970-01-01T05:32:21.213Z +node.appendChild call: cookieE zz 1970-01-01T01:42:01.598Z +node.appendChild call: cookieF null N/A --- Previous neighbor selection test --- # of node.appendChild calls: 6 # of node.removeChildren calls: 2 -node.appendChild call: cookieA 11 -node.appendChild call: cookieB 2 -node.appendChild call: cookieC foo -node.appendChild call: cookieD {other} -node.appendChild call: cookieE zz [selected] -node.appendChild call: cookieF null +node.appendChild call: cookieA 11 Session +node.appendChild call: cookieB 2 1970-01-01T00:00:00.001Z +node.appendChild call: cookieC foo 2018-12-17T14:31:30.000Z +node.appendChild call: cookieD {other} 1970-01-01T05:32:21.213Z +node.appendChild call: cookieE zz 1970-01-01T01:42:01.598Z [selected] +node.appendChild call: cookieF null N/A --- Inactive node test --- # of node.appendChild calls: 7 # of node.removeChildren calls: 2 -node.appendChild call: cookieA 11 -node.appendChild call: cookieB 2 -node.appendChild call: cookieC foo -node.appendChild call: cookieD {other} -node.appendChild call: cookieE zz -node.appendChild call: cookieF null -node.appendChild call: missing cookie [selected] +node.appendChild call: cookieA 11 Session +node.appendChild call: cookieB 2 1970-01-01T00:00:00.001Z +node.appendChild call: cookieC foo 2018-12-17T14:31:30.000Z +node.appendChild call: cookieD {other} 1970-01-01T05:32:21.213Z +node.appendChild call: cookieE zz 1970-01-01T01:42:01.598Z +node.appendChild call: cookieF null N/A +node.appendChild call: missing cookie Session [selected] -------- Sort cookies --------
diff --git a/third_party/blink/web_tests/http/tests/devtools/components/cookies-table.js b/third_party/blink/web_tests/http/tests/devtools/components/cookies-table.js index 2b6adeb..b6f80bf 100644 --- a/third_party/blink/web_tests/http/tests/devtools/components/cookies-table.js +++ b/third_party/blink/web_tests/http/tests/devtools/components/cookies-table.js
@@ -16,7 +16,7 @@ calls.appendChild.forEach(node => { const data = node._data; const selected = node._selected ? '[selected]' : ''; - TestRunner.addResult(`node.appendChild call: ${data.name} ${data.value} ${selected}`.trim()); + TestRunner.addResult(`node.appendChild call: ${data.name} ${data.value} ${data.expires} ${selected}`.trim()); }); } @@ -140,12 +140,12 @@ function run() { const cookieData = [ - {name: 'cookieA', value: '11', path: '/zzz', domain: 'example.com'}, - {name: 'cookieB', value: '2', path: '/abc', domain: '.example.com'}, - {name: 'cookieC', value: 'foo', path: '/', domain: 'abc.example.com'}, - {name: 'cookieD', value: '{other}', path: '/aa', domain: '.other.com'}, - {name: 'cookieE', value: 'zz', path: '/gg', domain: 'z.example.com'}, - {name: 'cookieF', value: 'null', path: '/', domain: 'example.com'}, + {name: 'cookieA', value: '11', path: '/zzz', domain: 'example.com', expires: 0}, + {name: 'cookieB', value: '2', path: '/abc', domain: '.example.com', expires: 1}, + {name: 'cookieC', value: 'foo', path: '/', domain: 'abc.example.com', expires: 1545057090000}, + {name: 'cookieD', value: '{other}', path: '/aa', domain: '.other.com', expires: 19941213}, + {name: 'cookieE', value: 'zz', path: '/gg', domain: 'z.example.com', expires: 6121598}, + {name: 'cookieF', value: 'null', path: '/', domain: 'example.com', expires: -1000}, ]; TestRunner.addResult('\n-------- RebuildTable --------\n'); testRebuildTable(cookieData);
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-trim-long-traces-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-trim-long-traces-expected.txt new file mode 100644 index 0000000..0cda3ff4 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/devtools/console/console-trim-long-traces-expected.txt
@@ -0,0 +1,71 @@ +Tests that a long stack trace is truncated. + +Message count: 2 + +console-trim-long-traces.js:15 console.trace +recursive @ console-trim-long-traces.js:15 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +(anonymous) @ console-trim-long-traces.js:18 + +console-trim-long-traces.js:15 console.trace +recursive @ console-trim-long-traces.js:15 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +recursive @ console-trim-long-traces.js:13 +(anonymous) @ console-trim-long-traces.js:19 +Show 21 more frames +
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-trim-long-traces.js b/third_party/blink/web_tests/http/tests/devtools/console/console-trim-long-traces.js new file mode 100644 index 0000000..ed88452b --- /dev/null +++ b/third_party/blink/web_tests/http/tests/devtools/console/console-trim-long-traces.js
@@ -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. + +(async function() { + TestRunner.addResult(`Tests that a long stack trace is truncated.\n`); + + await TestRunner.loadModule('console_test_runner'); + await TestRunner.showPanel('console'); + await TestRunner.evaluateInPagePromise(` + function recursive(n) { + if (n > 1) { + return recursive(n-1); + } else { + return console.trace(); + } + } + recursive(10); + recursive(50); + `); + + await ConsoleTestRunner.waitForConsoleMessagesPromise(2); + ConsoleTestRunner.dumpConsoleMessages(false, false, messageElement => '\n' + messageElement.deepTextContent().replace(/\u200b/g, '')); + TestRunner.completeTest(); +})();
diff --git a/third_party/blink/web_tests/http/tests/security/isolatedWorld/resources/javascript-url-bypass.js b/third_party/blink/web_tests/http/tests/security/isolatedWorld/resources/javascript-url-bypass.js index 1d2cb028..c0697ea 100644 --- a/third_party/blink/web_tests/http/tests/security/isolatedWorld/resources/javascript-url-bypass.js +++ b/third_party/blink/web_tests/http/tests/security/isolatedWorld/resources/javascript-url-bypass.js
@@ -28,7 +28,9 @@ function test() { function setIframeSrcToJavaScript(num) { var iframe = document.getElementById('testiframe'); - iframe.src = "javascript:alert('iframe javascript: src running')"; + // Provide a body in the iframe src to trigger an onload event once + // execution has finished. + iframe.src = "javascript:alert('iframe javascript: src running') || 'alerted'"; } alert("Running test #" + tests + "\n");
diff --git a/third_party/blink/web_tests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html b/third_party/blink/web_tests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html index 1aff943..bdb64ed 100644 --- a/third_party/blink/web_tests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html +++ b/third_party/blink/web_tests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html
@@ -6,6 +6,7 @@ <script> if (window.testRunner) { testRunner.dumpAsText(); + testRunner.waitUntilDone(); testRunner.dumpChildFrames(); } @@ -27,6 +28,9 @@ var iframe = document.getElementById("aFrame"); iframe.src = url; + iframe.addEventListener('load', () => { + testRunner.notifyDone(); + }); </script> </body> </html>
diff --git a/third_party/blink/web_tests/http/tests/security/javascriptURL/xss-ALLOWED-to-javascript-url-from-javscript-url.html b/third_party/blink/web_tests/http/tests/security/javascriptURL/xss-ALLOWED-to-javascript-url-from-javscript-url.html index 8967138b..c6ddd0f 100644 --- a/third_party/blink/web_tests/http/tests/security/javascriptURL/xss-ALLOWED-to-javascript-url-from-javscript-url.html +++ b/third_party/blink/web_tests/http/tests/security/javascriptURL/xss-ALLOWED-to-javascript-url-from-javscript-url.html
@@ -6,6 +6,7 @@ <script> if (window.testRunner) { testRunner.dumpAsText(); + testRunner.waitUntilDone(); testRunner.dumpChildFrames(); } @@ -30,6 +31,10 @@ var iframe = document.getElementById("aFrame"); iframe.src = url; + + iframe.addEventListener('load', () => { + testRunner.notifyDone(); + }); </script> </body> </html>
diff --git a/third_party/blink/web_tests/loader/iframe-sync-loads-expected.txt b/third_party/blink/web_tests/loader/iframe-sync-loads-expected.txt index 1159c11..686d3b3 100644 --- a/third_party/blink/web_tests/loader/iframe-sync-loads-expected.txt +++ b/third_party/blink/web_tests/loader/iframe-sync-loads-expected.txt
@@ -1,4 +1,4 @@ - sync : src = javascript:"content" +ASYNC : src = javascript:"content" ASYNC : src = data:text/html,content ASYNC : srcdoc = "content" done
diff --git a/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt index aa8a3f01..24bb05d 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt +++ b/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt
@@ -3,7 +3,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". [INTERFACES] -interface Bluetooth +interface Bluetooth : EventTarget attribute @@toStringTag method constructor method requestDevice
diff --git a/third_party/blink/web_tests/virtual/bidi-caret-affinity/editing/README.txt b/third_party/blink/web_tests/virtual/bidi-caret-affinity/editing/README.txt new file mode 100644 index 0000000..812a51d --- /dev/null +++ b/third_party/blink/web_tests/virtual/bidi-caret-affinity/editing/README.txt
@@ -0,0 +1,3 @@ +# This suite runs the tests in editing/ with +# --enable-blink-features=BidiCaretAffinity +# See design doc for more details: http://bit.ly/2xVMjdc
diff --git a/third_party/blink/web_tests/virtual/mouseevent_fractional/fast/events/javascript-uri-navigation-blocked-in-unload-handler-expected.txt b/third_party/blink/web_tests/virtual/mouseevent_fractional/fast/events/javascript-uri-navigation-blocked-in-unload-handler-expected.txt index 695552ac..8b13789 100644 --- a/third_party/blink/web_tests/virtual/mouseevent_fractional/fast/events/javascript-uri-navigation-blocked-in-unload-handler-expected.txt +++ b/third_party/blink/web_tests/virtual/mouseevent_fractional/fast/events/javascript-uri-navigation-blocked-in-unload-handler-expected.txt
@@ -1,2 +1 @@ -PASS: script executed
diff --git a/third_party/blink/web_tests/virtual/threaded/external/wpt/requestidlecallback/README.txt b/third_party/blink/web_tests/virtual/threaded/external/wpt/requestidlecallback/README.txt new file mode 100644 index 0000000..11ad6bf --- /dev/null +++ b/third_party/blink/web_tests/virtual/threaded/external/wpt/requestidlecallback/README.txt
@@ -0,0 +1,2 @@ +# This suite runs the test in external/wpt/requestidlecallack/ with +# --enable-threaded-compositing
diff --git a/third_party/blink/web_tests/virtual/user-activation-v2/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt b/third_party/blink/web_tests/virtual/user-activation-v2/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt index 56f72c0..14cad64 100644 --- a/third_party/blink/web_tests/virtual/user-activation-v2/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt +++ b/third_party/blink/web_tests/virtual/user-activation-v2/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
@@ -41,6 +41,7 @@ PASS window.cached_navigator.userAgent is '' PASS window.cached_navigator.vendor is window.navigator.vendor PASS window.cached_navigator.vendorSub is '' +PASS window.cached_navigator_bluetooth.onadvertisementreceived is null PASS window.cached_navigator_connection.onchange is null PASS window.cached_navigator_connection.ontypechange is null PASS window.cached_navigator_connection.saveData is false
diff --git a/third_party/blink/web_tests/virtual/user-activation-v2/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt b/third_party/blink/web_tests/virtual/user-activation-v2/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt index 0e46b5e8..f4cc514 100644 --- a/third_party/blink/web_tests/virtual/user-activation-v2/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt +++ b/third_party/blink/web_tests/virtual/user-activation-v2/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
@@ -41,6 +41,7 @@ PASS window.cached_navigator.userAgent is '' PASS window.cached_navigator.vendor is window.navigator.vendor PASS window.cached_navigator.vendorSub is '' +PASS window.cached_navigator_bluetooth.onadvertisementreceived is null PASS window.cached_navigator_connection.onchange is null PASS window.cached_navigator_connection.ontypechange is null PASS window.cached_navigator_connection.saveData is false
diff --git a/third_party/blink/web_tests/virtual/user-activation-v2/fast/events/javascript-uri-navigation-blocked-in-unload-handler-expected.txt b/third_party/blink/web_tests/virtual/user-activation-v2/fast/events/javascript-uri-navigation-blocked-in-unload-handler-expected.txt index 695552ac..8b13789 100644 --- a/third_party/blink/web_tests/virtual/user-activation-v2/fast/events/javascript-uri-navigation-blocked-in-unload-handler-expected.txt +++ b/third_party/blink/web_tests/virtual/user-activation-v2/fast/events/javascript-uri-navigation-blocked-in-unload-handler-expected.txt
@@ -1,2 +1 @@ -PASS: script executed
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index 6a76e056..18f905991 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -534,6 +534,47 @@ getter data getter timecode method constructor +interface BluetoothAdvertisingEvent : Event + attribute @@toStringTag + getter appearance + getter device + getter manufacturerData + getter name + getter rssi + getter serviceData + getter txPower + getter uuids + method constructor +interface BluetoothLEScan + attribute @@toStringTag + getter acceptAllAdvertisements + getter active + getter filters + getter keepRepeatedDevices + method constructor + method stop +interface BluetoothManufacturerDataMap + attribute @@toStringTag + getter size + method @@iterator + method constructor + method entries + method forEach + method get + method has + method keys + method values +interface BluetoothServiceDataMap + attribute @@toStringTag + getter size + method @@iterator + method constructor + method entries + method forEach + method get + method has + method keys + method values interface BroadcastChannel : EventTarget attribute @@toStringTag getter name
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-expected.txt index f27f170..9165eb1 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-expected.txt
@@ -3,10 +3,13 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". [INTERFACES] -interface Bluetooth +interface Bluetooth : EventTarget attribute @@toStringTag + getter onadvertisementreceived method constructor method requestDevice + method requestLEScan + setter onadvertisementreceived interface BluetoothCharacteristicProperties attribute @@toStringTag getter authenticatedSignedWrites
diff --git a/third_party/libFuzzer/BUILD.gn b/third_party/libFuzzer/BUILD.gn index 4131a526..8810d68 100644 --- a/third_party/libFuzzer/BUILD.gn +++ b/third_party/libFuzzer/BUILD.gn
@@ -10,12 +10,17 @@ "//build/config/sanitizers:default_sanitizer_flags", ] -fuzzing_engine_add_configs = [] - -if (is_msan) { - fuzzing_engine_add_configs += - [ "//build/config/sanitizers:default_sanitizer_flags_but_coverage" ] -} +# Add any sanitizer flags back. In MSAN builds, instrumenting libfuzzer with +# MSAN is necessary since all parts of the binary need to be instrumented for it +# to work. ASAN builds are more subtle: libfuzzer depends on features from the +# C++ STL. If it were not instrumented, templates would be insantiated without +# ASAN from libfuzzer and with ASAN in other TUs. The linker might merge +# instrumented template instantiations with non-instrumented ones (which could +# have a different ABI) in the final binary, which is problematic for TUs +# expecting one particular ABI (https://crbug.com/915422). The other sanitizers +# are added back for the same reason. +fuzzing_engine_add_configs = + [ "//build/config/sanitizers:default_sanitizer_flags_but_coverage" ] source_set("libfuzzer") { sources = [
diff --git a/third_party/libvpx/README.chromium b/third_party/libvpx/README.chromium index 934a5eb..605c45d 100644 --- a/third_party/libvpx/README.chromium +++ b/third_party/libvpx/README.chromium
@@ -5,9 +5,9 @@ License File: source/libvpx/LICENSE Security Critical: yes -Date: Saturday December 15 2018 +Date: Tuesday December 18 2018 Branch: master -Commit: d8f89c49e17bec211eaedcf4eeeee4facaaf5513 +Commit: 57f7c6f19144786c57d5cfc8e878765bd9944baf Description: Contains the sources used to compile libvpx binaries used by Google Chrome and
diff --git a/third_party/libvpx/source/config/vpx_version.h b/third_party/libvpx/source/config/vpx_version.h index daa32169..64c2c16 100644 --- a/third_party/libvpx/source/config/vpx_version.h +++ b/third_party/libvpx/source/config/vpx_version.h
@@ -2,7 +2,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 7 #define VERSION_PATCH 0 -#define VERSION_EXTRA "1515-gd8f89c49e" +#define VERSION_EXTRA "1534-g57f7c6f19" #define VERSION_PACKED ((VERSION_MAJOR<<16)|(VERSION_MINOR<<8)|(VERSION_PATCH)) -#define VERSION_STRING_NOSP "v1.7.0-1515-gd8f89c49e" -#define VERSION_STRING " v1.7.0-1515-gd8f89c49e" +#define VERSION_STRING_NOSP "v1.7.0-1534-g57f7c6f19" +#define VERSION_STRING " v1.7.0-1534-g57f7c6f19"
diff --git a/third_party/protobuf/BUILD.gn b/third_party/protobuf/BUILD.gn index e0ea60c..8e02f21 100644 --- a/third_party/protobuf/BUILD.gn +++ b/third_party/protobuf/BUILD.gn
@@ -218,6 +218,10 @@ # Perfetto uses the full library for testing. "//third_party/perfetto/protos/ftrace:full", "//third_party/perfetto/gn:protobuf_full_deps", + + # The SQLite fuzzer's corpus generator needs protobuf_full and is not + # included in Chrome. + "//third_party/sqlite:sqlite3_lpm_corpus_gen", ] sources = protobuf_lite_sources + [
diff --git a/third_party/sqlite/BUILD.gn b/third_party/sqlite/BUILD.gn index 840a05a..2f89a7b 100644 --- a/third_party/sqlite/BUILD.gn +++ b/third_party/sqlite/BUILD.gn
@@ -205,6 +205,10 @@ # This is to fuzz SQLite's resilience to database corruption. "SQLITE_ENABLE_DESERIALIZE", ] + + # The progress callback is used in fuzzing to cancel long-running queries + # so we don't spend too much time on them. + defines -= [ "SQLITE_OMIT_PROGRESS_CALLBACK" ] } } @@ -463,6 +467,7 @@ "max_len=2111000", "len_control=0", ] + seed_corpus = "fuzz/lpm_fuzzer_seed_corpus/" } # FTS3-focused LPM-based fuzzer test. @@ -547,6 +552,22 @@ ] } +# Generates a good corpus for the sqlite_lpm_fuzzer +if (use_fuzzing_engine) { + executable("sqlite3_lpm_corpus_gen") { + sources = [ + "fuzz/sql_generate_corpus.cc", + "fuzz/sql_query_proto_to_string.cc", + "fuzz/sql_query_proto_to_string.h", + ] + deps = [ + ":sqlite3_lpm_fuzzer_core", + "//base", + "//third_party/protobuf:protobuf_full", + ] + } +} + config("sqlite3_dbfuzz2_config") { cflags = [ "-Wno-sign-compare" ] configs = [ ":sqlite_warnings" ]
diff --git a/third_party/sqlite/fuzz/DEPS b/third_party/sqlite/fuzz/DEPS index 5199d44..8eb68bc 100644 --- a/third_party/sqlite/fuzz/DEPS +++ b/third_party/sqlite/fuzz/DEPS
@@ -1 +1 @@ -include_rules = [ '+testing/libfuzzer/proto' ] +include_rules = [ '+testing/libfuzzer/proto', '+base' ]
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries0 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries0 new file mode 100644 index 0000000..7a36870f --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries0 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries1 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries1 new file mode 100644 index 0000000..f285392 --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries1 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries10 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries10 new file mode 100644 index 0000000..cbc9fa6 --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries10 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries11 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries11 new file mode 100644 index 0000000..9ee13e90 --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries11 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries12 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries12 new file mode 100644 index 0000000..04ae159 --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries12 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries13 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries13 new file mode 100644 index 0000000..25fc7c70 --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries13 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries14 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries14 new file mode 100644 index 0000000..e4e0a74 --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries14 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries15 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries15 new file mode 100644 index 0000000..6ef088e --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries15 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries16 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries16 new file mode 100644 index 0000000..f45f4a2 --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries16 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries17 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries17 new file mode 100644 index 0000000..6d48cb7 --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries17 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries18 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries18 new file mode 100644 index 0000000..4fb9deb --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries18 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries19 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries19 new file mode 100644 index 0000000..529b54e --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries19 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries2 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries2 new file mode 100644 index 0000000..c51cd5f --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries2 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries3 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries3 new file mode 100644 index 0000000..530de34 --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries3 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries4 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries4 new file mode 100644 index 0000000..b879fe2 --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries4 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries5 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries5 new file mode 100644 index 0000000..c443de6 --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries5 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries6 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries6 new file mode 100644 index 0000000..3841499 --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries6 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries7 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries7 new file mode 100644 index 0000000..a90d0884 --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries7 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries8 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries8 new file mode 100644 index 0000000..98ede46 --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries8 Binary files differ
diff --git a/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries9 b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries9 new file mode 100644 index 0000000..4d4c15c --- /dev/null +++ b/third_party/sqlite/fuzz/lpm_fuzzer_seed_corpus/corpus_queries9 Binary files differ
diff --git a/third_party/sqlite/fuzz/sql_fuzzer.cc b/third_party/sqlite/fuzz/sql_fuzzer.cc index e7fdafc..7003a31f 100644 --- a/third_party/sqlite/fuzz/sql_fuzzer.cc +++ b/third_party/sqlite/fuzz/sql_fuzzer.cc
@@ -18,6 +18,14 @@ // 12. CORPUS Indexes on expressions (https://www.sqlite.org/expridx.html) and // other places using functions on columns??? // 17. Generate a nice big random, well-formed corpus. +// 18. Possibly very difficult for fuzzer to find certain areas of code, because +// some protobufs need to be mutated together. For example, an index on an +// expression is useless to change, if you don't change the SELECTs that use +// that expression. May need to create a mechanism for the protobufs to +// "register" (in the c++ fuzzer) expressions being used for certain purposes, +// and then protobufs can simple reference those expressions later (similarly to +// columns or tables, with just an index). This should be added if coverage +// shows it is the case. // FIXME in the future // 1. Rest of the pragmas
diff --git a/third_party/sqlite/fuzz/sql_generate_corpus.cc b/third_party/sqlite/fuzz/sql_generate_corpus.cc new file mode 100644 index 0000000..365e889 --- /dev/null +++ b/third_party/sqlite/fuzz/sql_generate_corpus.cc
@@ -0,0 +1,967 @@ +#include <unistd.h> +#include <iostream> +#include <string> +#include <vector> + +#include "base/command_line.h" +#include "base/files/file.h" +#include "base/files/file_path.h" +#include "base/no_destructor.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "base/time/default_clock.h" +// TODO(mpdenton) okay to include this? Otherwise I'm copying it into this file +// Tehcnically the std random number engines are banned in Chrome but if this +// used base::Rand* this turns milliseconds into hours. +#include "third_party/libFuzzer/src/FuzzerRandom.h" +#include "third_party/sqlite/fuzz/sql_query_grammar.pb.h" +#include "third_party/sqlite/fuzz/sql_query_proto_to_string.h" +#include "third_party/sqlite/fuzz/sql_run_queries.h" + +using namespace sql_query_grammar; + +// TODO(mpdenton): +// 2. Add functionality to start with a specific database so that the +// fuzzer doesn't waste so much time getting a sufficiently complicated +// database. +// 3. FTS3 Corpus + +namespace { +constexpr int kMinNumInsertions = 15; +constexpr int kMaxNumInsertions = 20; +constexpr int kMinNumIndexes = 5; +constexpr int kMaxNumIndexes = 8; +constexpr int kMinNumSelects = 3; +constexpr int kMaxNumSelects = 6; +constexpr int kMinNumJoins = 3; +constexpr int kMaxNumJoins = 3; +constexpr int kMinNumUpdates = 15; +constexpr int kMaxNumUpdates = 20; +constexpr int kMinNumDeletes = 5; +constexpr int kMaxNumDeletes = 5; +constexpr int kMinNumOthers = 10; +constexpr int kMaxNumOthers = 10; +} // namespace + +fuzzer::Random& GetRandom() { + static base::NoDestructor<fuzzer::Random> rand([] { + unsigned seed = base::DefaultClock::GetInstance() + ->Now() + .ToDeltaSinceWindowsEpoch() + .InMicroseconds() + + getpid(); + return fuzzer::Random(seed); + }()); + return *rand; +} + +// Inclusive range. +int RandInt(int min, int max) { + return GetRandom()(max - min + 1) + min; +} + +void RandBytes(void* output, size_t output_len) { + uint8_t* out = static_cast<uint8_t*>(output); + for (size_t i = 0; i < output_len / sizeof(size_t); i++) { + size_t rand_num = GetRandom()(); + for (size_t j = 0; j < sizeof(size_t); j++) { + *out = *reinterpret_cast<uint8_t*>(&rand_num); + out++; + rand_num >>= 8; + } + } + size_t rand_num = GetRandom()(); + for (size_t j = 0; j < output_len % sizeof(size_t); j++) { + *out = *reinterpret_cast<uint8_t*>(&rand_num); + out++; + rand_num >>= 8; + } +} + +std::string RandBytesAsString(size_t length) { + std::string result; + RandBytes(base::WriteInto(&result, length + 1), length); + return result; +} + +uint64_t RandUint64() { + if (sizeof(size_t) == sizeof(uint64_t)) + return GetRandom()(); + + CHECK(sizeof(size_t) == sizeof(uint32_t)); + uint64_t rand = GetRandom()(); + rand <<= 32; + rand |= GetRandom()(); + return rand; +} + +namespace i { +struct Table { + uint32_t table_num; + int num_columns; + std::vector<CastTypeName::CastTypeNameEnum> col_types; + std::vector<std::unique_ptr<Expr>> index_exprs; +}; + +struct Schema { + int num_tables; + std::vector<i::Table> tables; +}; +} // namespace i + +// WOW, a template AND a macro??? :) +template <typename T> +int GetRandomEnum(T is_valid_fn, int min, int max) { + int r; + while (!is_valid_fn(r = RandInt(min, max))) + ; + return r; +} + +#define RANDOM_ENUM(CLASS_NAME, ENUM_NAME) \ + static_cast<CLASS_NAME::ENUM_NAME>( \ + GetRandomEnum(CLASS_NAME::ENUM_NAME##_IsValid, \ + CLASS_NAME::ENUM_NAME##_MIN, CLASS_NAME::ENUM_NAME##_MAX)) + +std::set<uint32_t> GetRandomNums(size_t size, uint32_t max_num) { + std::set<unsigned int> ret; + while (ret.size() < size) + ret.insert(RandInt(0, max_num)); + return ret; +} + +template <typename T> +std::set<T> GetRandomSubset(const std::set<T>& s, size_t size) { + std::set<T> ret; + std::set<uint32_t> indices = GetRandomNums(size, s.size() - 1); + + auto it = s.begin(); + for (unsigned int i = 0; i < s.size(); i++) { + if (indices.count(i) > 0) { + ret.insert(*it); + } + it++; + } + + return ret; +} + +inline ColumnDef* CreateDefaultColDef(ColumnDef* cd) { + cd->mutable_col()->set_column(0); + return cd; +} + +inline ComplicatedExpr* CreateDefaultCompExpr(ComplicatedExpr* ce) { + ce->mutable_lit_val(); + return ce; +} + +inline void CreateColumn(Column* col_ptr, uint32_t col) { + col_ptr->set_column(col); +} + +inline void CreateTableFromUint32(Table* table_ptr, uint32_t table) { + table_ptr->set_table(table); +} + +inline void CreateSchemaTable(ExprSchemaTable* e, i::Table* table) { + CreateTableFromUint32(e->mutable_table_name(), table->table_num); +} + +inline void CreateColumnExpr(Expr* e, uint32_t col, i::Table* table) { + ExprSchemaTableColumn* stc = + CreateDefaultCompExpr(e->mutable_comp_expr())->mutable_expr_stc(); + CreateColumn(stc->mutable_col(), col); + if (table) + CreateTableFromUint32(stc->mutable_table(), table->table_num); +} + +std::set<uint32_t> GenerateColumnList(ColumnList* ret, i::Table* table) { + std::set<uint32_t> cols; + for (int i = 0; i < RandInt(1, table->num_columns); i++) { + cols.insert(RandInt(0, table->num_columns - 1)); + } + std::set<uint32_t> cols_copy = cols; + auto it = cols.begin(); + CreateColumn(ret->mutable_col(), *it); + cols.erase(it); + ret->mutable_extra_cols()->Reserve(cols.size()); + for (uint32_t col : cols) { + CreateColumn(ret->mutable_extra_cols()->Add(), col); + } + return cols_copy; +} + +void GenerateNumericLit(NumericLiteral* nl) { + for (int i = 0; i < RandInt(1, 20); i++) { + nl->add_digits(RandInt(0, 9)); + } + nl->set_decimal_point(true); + for (int i = 0; i < RandInt(1, 20); i++) { + nl->add_dec_digits(RandInt(0, 9)); + } +} + +void GenerateLiteralValue(LiteralValue* ret, + CastTypeName::CastTypeNameEnum type) { + if (RandInt(1, 10) == 1) { + ret->set_special_val(RANDOM_ENUM(LiteralValue, SpecialVal)); + return; + } + + if (type == CastTypeName::INTEGER || + (type == CastTypeName::NUMERIC && RandInt(1, 2) == 1)) { + if (RandInt(1, 3) == 1) + ret->set_num_lit((int64_t)RandInt(1, 3)); + else + ret->set_num_lit((int64_t)RandUint64()); + } else if (type == CastTypeName::TEXT) { + if (RandInt(1, 3) == 1) + ret->set_string_lit("a"); + else + // string literals too often have unreadable chars, so instead of rand + // bytes just use a couple extra #'s + ret->set_string_lit("#####"); + } else if (type == CastTypeName::BLOB) { + if (RandInt(1, 3) == 1) + ret->set_blob_lit("a"); + else + ret->set_blob_lit(RandBytesAsString(5)); + } else if (type == CastTypeName::REAL) { + GenerateNumericLit(ret->mutable_numeric_lit()); + } else { + ret->set_special_val(RANDOM_ENUM(LiteralValue, SpecialVal)); + } +} + +void GenerateValuesStatement(ValuesStatement* v, + i::Table* table, + std::set<uint32_t> cols) { + int rand_num_values = RandInt(1, 10); + if (rand_num_values > 1) + v->mutable_extra_expr_lists()->Reserve(rand_num_values - 1); + for (int i = 0; i < rand_num_values; i++) { + ExprList* el; + if (i == 0) { + el = v->mutable_expr_list(); + } else { + el = v->mutable_extra_expr_lists()->Add(); + } + auto it = cols.begin(); + GenerateLiteralValue(el->mutable_expr()->mutable_lit_val(), + table->col_types[*it]); + it++; + el->mutable_extra_exprs()->Reserve(cols.size() - 1); + for (size_t i = 0; i < cols.size() - 1; i++) { + GenerateLiteralValue(el->mutable_extra_exprs()->Add()->mutable_lit_val(), + table->col_types[*it]); + it++; + } + } +} + +void GenerateWhereStatement(WhereStatement* where, + i::Schema* schema, + i::Table* table, + bool join = false) { + BinaryExpr* we = where->mutable_expr() + ->mutable_expr() + ->mutable_comp_expr() + ->mutable_binary_expr(); + + // TODO(mpdenton) exclude joins for now. + if (!join && table->index_exprs.size() != 0 && RandInt(1, 5) >= 4) { + // Use an indexed expression + *we->mutable_lhs() = + *table->index_exprs[RandInt(0, table->index_exprs.size() - 1)]; + we->set_op(BINOP_LEQ); + GenerateLiteralValue(we->mutable_rhs()->mutable_lit_val(), + CastTypeName::NUMERIC); + return; + } + + // Otherwise just use a simple predicate + uint32_t col = RandInt(0, table->num_columns - 1); + ExprSchemaTableColumn* stc = + we->mutable_lhs()->mutable_comp_expr()->mutable_expr_stc(); + CreateColumn(stc->mutable_col(), col); + if (join) + CreateTableFromUint32(stc->mutable_table(), table->table_num); + if (table->col_types[col] == CastTypeName::BLOB) { + we->set_op(BINOP_NOTEQ); + we->mutable_rhs()->mutable_lit_val()->set_special_val( + LiteralValue::VAL_NULL); + } else if (table->col_types[col] == CastTypeName::TEXT) { + we->set_op(BINOP_REGEXP); + we->mutable_rhs()->mutable_lit_val()->set_string_lit(".*"); + } else { + we->set_op(BINOP_LEQ); + we->mutable_rhs()->mutable_lit_val()->set_num_lit(RandUint64()); + } +} + +void GenerateInsertion(Insert* i, i::Schema* schema, i::Table* table) { + // TODO(mpdenton) generate With statement + // i->set_insert_type(RANDOM_ENUM(Insert, InsertType)); + + if (RandInt(1, 2) == 1) + i->set_insert_type(Insert::INSERT); + else + i->set_insert_type(Insert::REPLACE); + + SchemaTableAsAlias* staa = i->mutable_staa(); + CreateSchemaTable(staa->mutable_schema_table(), table); + + if (RandInt(1, 5) >= 2) { + std::set<uint32_t> cols = GenerateColumnList(i->mutable_col_list(), table); + GenerateValuesStatement(i->mutable_values(), table, cols); + } +} + +void GenerateUpdate(Update* u, i::Schema* schema, i::Table* table) { + SchemaTableAsAlias* staa = u->mutable_qtn()->mutable_staa(); + CreateSchemaTable(staa->mutable_schema_table(), table); + + ColEqualsExpr* cee = u->mutable_ucp2()->mutable_cee(); + uint32_t col = RandInt(0, table->num_columns - 1); + CreateColumn(cee->mutable_col(), col); + GenerateLiteralValue(cee->mutable_expr()->mutable_lit_val(), + table->col_types[col]); + + if (RandInt(1, 10) >= 2) + GenerateWhereStatement(u->mutable_ucp2()->mutable_where_stmt(), schema, + table); +} + +void GenerateDelete(Delete* d, i::Schema* schema, i::Table* table) { + SchemaTableAsAlias* staa = d->mutable_qtn()->mutable_staa(); + CreateSchemaTable(staa->mutable_schema_table(), table); + + if (RandInt(1, 20) >= 2) + GenerateWhereStatement(d->mutable_where(), schema, table); +} + +void GenerateCreateTable(CreateTable* ct, i::Schema* schema, i::Table* table) { + ct->set_if_not_exists(false); + if (RandInt(1, 4) == 1) { + ct->set_temp_modifier(TM_TEMP); + } + + CreateSchemaTable(ct->mutable_schema_table(), table); + + if (table->num_columns > 1) + ct->mutable_op1()->mutable_extra_col_defs()->Reserve(table->num_columns - + 1); + + for (int i = 0; i < table->num_columns; i++) { + ColumnDef* col_def; + if (i == 0) + col_def = ct->mutable_op1()->mutable_col_def(); + else + col_def = ct->mutable_op1()->mutable_extra_col_defs()->Add(); + CreateColumn(col_def->mutable_col(), i); + col_def->mutable_type_name()->mutable_ctn()->set_type_enum( + table->col_types[i]); + // Set default values + GenerateLiteralValue( + col_def->add_col_constraints()->mutable_opt2()->mutable_lit_val(), + table->col_types[i]); + } +} + +bool IsNumeric(CastTypeName::CastTypeNameEnum type) { + return (type == CastTypeName::NUMERIC || type == CastTypeName::INTEGER || + type == CastTypeName::REAL); +} + +Expr* GenerateJoinConstaints(i::Table* table, + const std::vector<i::Table*>& join_tables) { + std::vector<i::Table*> all_tables = join_tables; + all_tables.push_back(table); + // Decide some columns have to be equal + std::vector<std::pair<ExprSchemaTableColumn*, ExprSchemaTableColumn*>> + equal_cols; + std::vector<BinaryOperator> comparison_ops; + + // Would be better if the num_constraints + do { + ExprSchemaTableColumn* a = new ExprSchemaTableColumn; + ExprSchemaTableColumn* b = new ExprSchemaTableColumn; + int table_index_a = RandInt(0, all_tables.size() - 1); + CreateTableFromUint32(a->mutable_table(), + all_tables[table_index_a]->table_num); + int table_index_b; + while ((table_index_b = RandInt(0, all_tables.size() - 1)) == table_index_a) + ; + CreateTableFromUint32(b->mutable_table(), + all_tables[table_index_b]->table_num); + + uint32_t col_a = RandInt(0, all_tables[table_index_a]->num_columns - 1); + uint32_t col_b = RandInt(0, all_tables[table_index_b]->num_columns - 1); + CreateColumn(a->mutable_col(), col_a); + CreateColumn(b->mutable_col(), col_b); + + equal_cols.push_back({a, b}); + + // If both columns are numeric, small chance of using a comparison op + // instead. + if (IsNumeric(all_tables[table_index_a]->col_types[col_a]) && + IsNumeric(all_tables[table_index_b]->col_types[col_b]) && + RandInt(1, 2) == 1) + comparison_ops.push_back(BINOP_LEQ); + else + comparison_ops.push_back(BINOP_EQ); + } while (RandInt(1, 3) >= 2); + + // Actually generate the expressions. + Expr* initial_expr = new Expr; + Expr* curr_expr = initial_expr; + for (size_t i = 0; i < equal_cols.size() - 1; i++) { + BinaryExpr* bin_expr = CreateDefaultCompExpr(curr_expr->mutable_comp_expr()) + ->mutable_binary_expr(); + BinaryExpr* lhs_bin_expr = + bin_expr->mutable_lhs()->mutable_comp_expr()->mutable_binary_expr(); + lhs_bin_expr->mutable_lhs()->mutable_comp_expr()->set_allocated_expr_stc( + equal_cols[i].first); + lhs_bin_expr->set_op(comparison_ops[i]); + lhs_bin_expr->mutable_rhs()->mutable_comp_expr()->set_allocated_expr_stc( + equal_cols[i].second); + + if (RandInt(1, 2) == 1) + bin_expr->set_op(BINOP_AND); + else + bin_expr->set_op(BINOP_OR); + + curr_expr = bin_expr->mutable_rhs(); + } + // Finish off final expr + size_t last_index = equal_cols.size() - 1; + BinaryExpr* bin_expr = CreateDefaultCompExpr(curr_expr->mutable_comp_expr()) + ->mutable_binary_expr(); + bin_expr->mutable_lhs()->mutable_comp_expr()->set_allocated_expr_stc( + equal_cols[last_index].first); + bin_expr->set_op(comparison_ops[last_index]); + bin_expr->mutable_rhs()->mutable_comp_expr()->set_allocated_expr_stc( + equal_cols[last_index].second); + + return initial_expr; +} + +void GenerateFromStatement(FromStatement* from, + i::Schema* schema, + i::Table* table, + const std::vector<i::Table*>& join_tables) { + // TODO(mpdenton) join statements? + if (join_tables.size() == 0) { + SchemaTableAsAlias* staa = + from->mutable_tos3()->add_tos_list()->mutable_qtn()->mutable_staa(); + CreateSchemaTable(staa->mutable_schema_table(), table); + return; + } + + // Write some nice joins. + CreateSchemaTable(from->mutable_tos3() + ->mutable_join_clause() + ->mutable_tos() + ->mutable_qtn() + ->mutable_staa() + ->mutable_schema_table(), + table); + + // For each table in join_tables, write a JoinClauseCore that inner joins + // with some comparisons between any two columns + for (i::Table* curr_table : join_tables) { + JoinClauseCore* jcc = + from->mutable_tos3()->mutable_join_clause()->add_clauses(); + + // Just generate inner joins, fuzzer should be smart enough to find other + // join types. + jcc->mutable_join_op()->set_join_type(JoinOperator::INNER); + + // Fill in the join clause core with the current table + CreateSchemaTable(jcc->mutable_tos() + ->mutable_qtn() + ->mutable_staa() + ->mutable_schema_table(), + curr_table); + + jcc->mutable_join_constraint()->set_allocated_on_expr( + GenerateJoinConstaints(table, join_tables)); + } + + // TODO(mpdenton) multiple Tables with aliases? +} + +void GenerateGroupByStatement(GroupByStatement* gbs, + i::Schema* schema, + i::Table* table, + bool join = false) { + ExprSchemaTableColumn* stc = gbs->mutable_exprs() + ->mutable_expr() + ->mutable_comp_expr() + ->mutable_expr_stc(); + // fine to just pick a single random column. + CreateColumn(stc->mutable_col(), RandInt(0, table->num_columns - 1)); + if (join) + CreateTableFromUint32(stc->mutable_table(), table->table_num); +} + +std::set<uint32_t> GenerateSelectStatementCore( + SelectStatementCore* ssc, + i::Schema* schema, + i::Table* table, + std::vector<i::Table*> join_tables) { + if (RandInt(1, 2) == 1) { + ssc->set_s_or_d(SelectStatementCore::SELECT); + } else { + ssc->set_s_or_d(SelectStatementCore::SELECT_DISTINCT); + } + + std::set<uint32_t> cols; + if (join_tables.size() > 0) { + // This is a join. Add columns from all the tables and include the table. + for (size_t i = 0; i <= join_tables.size(); i++) { + i::Table* table2; + if (i == join_tables.size()) + table2 = table; + else + table2 = join_tables[i]; + + cols = GetRandomNums(RandInt(1, table2->num_columns - 1), + table2->num_columns - 1); + for (uint32_t col : cols) { + ExprSchemaTableColumn* stc = ssc->add_result_columns() + ->mutable_eca() + ->mutable_expr() + ->mutable_comp_expr() + ->mutable_expr_stc(); + CreateColumn(stc->mutable_col(), col); + CreateTableFromUint32(stc->mutable_table(), table2->table_num); + } + } + } else { + if (RandInt(1, 2) == 1) { + cols = GetRandomNums(RandInt(1, table->num_columns - 1), + table->num_columns - 1); + for (uint32_t col : cols) { + CreateColumn(ssc->add_result_columns()->mutable_col(), col); + } + } else { + AggregateFn* af = ssc->add_result_columns() + ->mutable_eca() + ->mutable_expr() + ->mutable_comp_expr() + ->mutable_fn_expr() + ->mutable_aggregate_fn(); + af->set_fn_name(RANDOM_ENUM(AggregateFn, FnName)); + af->set_distinct((bool)RandInt(0, 1)); + CreateColumn(af->mutable_col1(), RandInt(0, table->num_columns - 1)); + } + } + + bool join = join_tables.size() > 0; + + GenerateFromStatement(ssc->mutable_from(), schema, table, join_tables); + + if (RandInt(1, 3) >= 2) { + GenerateWhereStatement(ssc->mutable_where(), schema, table, join); + } + + if (RandInt(1, 3) == 1) { + GenerateGroupByStatement(ssc->mutable_groupby(), schema, table, join); + } + + return cols; +} + +void GenerateOrderByStatement(OrderByStatement* obs, + i::Schema* schema, + i::Table* table, + std::set<uint32_t> cols_tmp, + bool join = false) { + // TODO(mpdenton) exclude joins for now. + if (!join && table->index_exprs.size() != 0 && RandInt(1, 5) >= 4) { + // Use an indexed expression + *obs->mutable_ord_term()->mutable_expr() = + *table->index_exprs[RandInt(0, table->index_exprs.size() - 1)]; + return; + } + + std::set<uint32_t> cols = + GetRandomSubset(cols_tmp, RandInt(1, cols_tmp.size() - 1)); + + std::vector<uint32_t> v; + std::copy(cols.begin(), cols.end(), std::back_inserter(v)); + std::shuffle(v.begin(), v.end(), GetRandom()); + + i::Table* table_in_col = join ? table : nullptr; + auto it = v.begin(); + CreateColumnExpr(obs->mutable_ord_term()->mutable_expr(), *it, table_in_col); + it++; + for (size_t i = 0; i < v.size() - 1; i++) { + CreateColumnExpr(obs->add_extra_ord_terms()->mutable_expr(), *it, + table_in_col); + it++; + } +} + +void GenerateSelect(Select* s, + i::Schema* schema, + i::Table* table, + std::vector<i::Table*> join_tables = {}) { + // Could be empty. + std::set<uint32_t> cols = GenerateSelectStatementCore( + s->mutable_select_core(), schema, table, join_tables); + // TODO(mpdenton) + + if (RandInt(1, 2) == 1) { + GenerateOrderByStatement(s->mutable_orderby(), schema, table, + GetRandomNums(RandInt(1, table->num_columns - 1), + table->num_columns - 1), + join_tables.size() > 0); + } + + // Limits are not very interesting from a corpus standpoint. +} + +void InsertUpdateSelectOrDelete(SQLQuery* q, + i::Schema* main_schema, + int table_num) { + int rand = RandInt(1, 4); + if (rand == 1) { + GenerateInsertion(q->mutable_insert(), main_schema, + &main_schema->tables[table_num]); + } else if (rand == 2) { + GenerateDelete(q->mutable_delete_(), main_schema, + &main_schema->tables[table_num]); + } else if (rand == 3) { + GenerateUpdate(q->mutable_update(), main_schema, + &main_schema->tables[table_num]); + } else if (rand == 4) { + GenerateSelect(q->mutable_select(), main_schema, + &main_schema->tables[table_num]); + } +} + +inline ExprSchemaTableColumn* GetSTC(Expr* expr) { + return CreateDefaultCompExpr(expr->mutable_comp_expr())->mutable_expr_stc(); +} + +Expr* GenerateCreateIndex(CreateIndex* ci, + i::Schema* schema, + i::Table* table, + std::set<uint32_t>& free_index_nums) { + CHECK(free_index_nums.size() != 0); + + std::set<uint32_t> index_num_set = GetRandomSubset(free_index_nums, 1); + uint32_t index_num = *index_num_set.begin(); + ci->mutable_index()->set_index(index_num); + free_index_nums.erase(index_num); + CreateTableFromUint32(ci->mutable_table(), table->table_num); + + if (RandInt(1, 3) >= 2) { + Expr* expr = new Expr; + int expr_type = RandInt(1, 2); + if (expr_type == 1) { + // Select two random columns of the table, add or subtract them. + uint32_t col1 = RandInt(0, table->num_columns - 1); + uint32_t col2 = RandInt(0, table->num_columns - 1); + + BinaryExpr* bin_expr = CreateDefaultCompExpr(expr->mutable_comp_expr()) + ->mutable_binary_expr(); + ExprSchemaTableColumn* lhs_stc = GetSTC(bin_expr->mutable_lhs()); + ExprSchemaTableColumn* rhs_stc = GetSTC(bin_expr->mutable_rhs()); + + CreateColumn(lhs_stc->mutable_col(), col1); + CreateColumn(rhs_stc->mutable_col(), col2); + + // TODO(mpdenton) perhaps set the tables here? The tables must not be set + // for CREATE INDEX, but MUST be set for JOINs to avoid ambiguous columns. + // Does it still count as the same expression if the table is included in + // the JOIN but not the CREATE INDEX? + if (RandInt(1, 2) == 1) + bin_expr->set_op(BINOP_PLUS); + else + bin_expr->set_op(BINOP_MINUS); + } else if (expr_type == 2) { + // Or, apply abs to a single column. + OneArgFn* oaf = CreateDefaultCompExpr(expr->mutable_comp_expr()) + ->mutable_fn_expr() + ->mutable_simple_fn() + ->mutable_one_arg_fn(); + oaf->set_fn_enum(OneArgFn::ABS); + uint32_t col = RandInt(0, table->num_columns - 1); + ExprSchemaTableColumn* stc = GetSTC(oaf->mutable_arg1()); + CreateColumn(stc->mutable_col(), col); + // TODO(mpdenton) see above about setting tables. + } + + ci->mutable_icol_list()->mutable_indexed_col()->set_allocated_expr(expr); + + // Make a copy that isn't owned by another protobuf + Expr* ret_expr = new Expr; + *ret_expr = *expr; + + return ret_expr; + } + + IndexedColumnList* icol_list = ci->mutable_icol_list(); + std::set<uint32_t> cols = + GetRandomNums(RandInt(1, table->num_columns - 1), table->num_columns - 1); + bool first; + for (uint32_t col : cols) { + IndexedColumn* icol; + if (first) { + first = false; + icol = icol_list->mutable_indexed_col(); + } else { + icol = icol_list->add_extra_indexed_cols(); + } + CreateColumn(icol->mutable_col(), col); + } + + return NULL; +} + +namespace { +enum class GenQueryInstr { + SUCCESS, + MOVE_ON, + TRY_AGAIN, +}; +} + +template <typename T> +void GenQueries(SQLQueries& queries, + int min, + int max, + bool txn, + int num_tables, + T gen) { + queries.mutable_extra_queries()->Reserve(queries.extra_queries_size() + max + + 2); + SQLQuery* q; + if (txn) { + q = new SQLQuery; + q->mutable_begin_txn(); // constructs a begin txn. + queries.mutable_extra_queries()->AddAllocated(q); + } + for (int i = 0; i < num_tables; i++) { + for (int j = 0; j < RandInt(min, max); j++) { + // continue; // TODO(mpdenton) + q = new SQLQuery; + GenQueryInstr success = gen(q, i); + // Try again + if (success != GenQueryInstr::SUCCESS) { + if (success == GenQueryInstr::TRY_AGAIN) + j--; + delete q; + continue; + } + queries.mutable_extra_queries()->AddAllocated(q); + } + } + if (txn) { + q = new SQLQuery; + q->mutable_commit_txn(); // constructs a begin txn. + queries.mutable_extra_queries()->AddAllocated(q); + } +} + +void FirstCreateTable(CreateTable* ct) { + ct->mutable_schema_table()->mutable_schema_name()->set_schema(5); + ct->mutable_schema_table()->mutable_schema_name()->set_main(false); + ct->mutable_schema_table()->mutable_schema_name()->set_temp(false); + ct->mutable_schema_table()->mutable_table_name()->set_table(0); + ct->set_if_not_exists(false); + ct->mutable_op(); +} + +SQLQueries GenCorpusEntry() { + // The answer is no, I free nothing at any point. + + // Create the tables, and attached databases with tables + // Schema schemas[i::kNumSchemas]; + // for (int i = 0; i < i::kNumSchemas; i++) { + // // schemas[i] = Schema{ + // // .num_tables = RandInt(1, 5); + // // }; + // } + SQLQueries queries; + FirstCreateTable(queries.mutable_create_table()); + + // Just get rid of the first CreateTable, it will error out but not screw up + // anything below + + i::Schema main_schema; + main_schema.num_tables = RandInt(1, 5); + + std::set<uint32_t> free_index_nums; + for (uint32_t i = 0; i < 10; i++) { + free_index_nums.insert(i); + } + + GenQueries( + queries, 1, 1, false, main_schema.num_tables, [&](SQLQuery* q, int i) { + i::Table t = i::Table{ + .table_num = i, + .num_columns = RandInt(1, 8), + }; + for (int j = 0; j < t.num_columns; j++) { + t.col_types.push_back(RANDOM_ENUM(CastTypeName, CastTypeNameEnum)); + } + main_schema.tables.push_back(std::move(t)); + GenerateCreateTable(q->mutable_create_table(), &main_schema, + &main_schema.tables[i]); + return GenQueryInstr::SUCCESS; + }); + + GenQueries(queries, kMinNumIndexes, kMaxNumIndexes, false, + main_schema.num_tables, [&](SQLQuery* q, int i) { + if (free_index_nums.size() == 0) + return GenQueryInstr::MOVE_ON; + + Expr* index_expr = + GenerateCreateIndex(q->mutable_create_index(), &main_schema, + &main_schema.tables[i], free_index_nums); + if (index_expr) + main_schema.tables[i].index_exprs.emplace_back(index_expr); + return GenQueryInstr::SUCCESS; + }); + + // Generate a bunch of inserts in a transaction (for speed) + GenQueries(queries, kMinNumInsertions, kMaxNumInsertions, true, + main_schema.num_tables, [&](SQLQuery* q, int i) { + GenerateInsertion(q->mutable_insert(), &main_schema, + &main_schema.tables[i]); + return GenQueryInstr::SUCCESS; + }); + + // Generate a bunch of interesting selects with GroupBys, OrderBys, aggregate + // functions, etc. + GenQueries(queries, kMinNumSelects, kMaxNumSelects, false, + main_schema.num_tables, [&](SQLQuery* q, int i) { + GenerateSelect(q->mutable_select(), &main_schema, + &main_schema.tables[i]); + return GenQueryInstr::SUCCESS; + }); + + // Generate lots of interesting JOINs. + if (main_schema.num_tables > 1) { + GenQueries(queries, kMinNumJoins, kMaxNumJoins, false, + main_schema.num_tables, [&](SQLQuery* q, int i) { + std::set<uint32_t> tables = + GetRandomNums(RandInt(1, main_schema.num_tables - 1), + main_schema.num_tables - 1); + tables.erase((uint32_t)i); + if (tables.size() == 0) { + // try again + return GenQueryInstr::TRY_AGAIN; + } + std::vector<i::Table*> tables_p; + for (uint32_t t : tables) { + tables_p.push_back(&main_schema.tables[t]); + } + GenerateSelect(q->mutable_select(), &main_schema, + &main_schema.tables[i], tables_p); + return GenQueryInstr::SUCCESS; + }); + } + + // Generate a bunch of interesting updates. + GenQueries(queries, kMinNumUpdates, kMaxNumUpdates, true, + main_schema.num_tables, [&](SQLQuery* q, int i) { + GenerateUpdate(q->mutable_update(), &main_schema, + &main_schema.tables[i]); + return GenQueryInstr::SUCCESS; + }); + + // Generate interesting deletes. + GenQueries(queries, kMinNumDeletes, kMaxNumDeletes, true, + main_schema.num_tables, [&](SQLQuery* q, int i) { + GenerateDelete(q->mutable_delete_(), &main_schema, + &main_schema.tables[i]); + return GenQueryInstr::SUCCESS; + }); + + // Do everything except joins. + GenQueries(queries, kMinNumOthers, kMaxNumOthers, true, + main_schema.num_tables, [&](SQLQuery* q, int i) { + InsertUpdateSelectOrDelete(q, &main_schema, i); + return GenQueryInstr::SUCCESS; + }); + + return queries; +} + +int main(int argc, char** argv) { + base::CommandLine cl(argc, argv); + + int num_entries; + if (!cl.HasSwitch("num_entries")) + LOG(FATAL) << "num_entries not specified."; + if (!base::StringToInt(cl.GetSwitchValueASCII("num_entries"), &num_entries)) + LOG(FATAL) << "num_entries not parseable as an int."; + + bool to_stdout = true; + base::FilePath dir_path; + if (cl.HasSwitch("corpus_dir")) { + to_stdout = false; + + dir_path = cl.GetSwitchValuePath("corpus_dir"); + base::File dir(dir_path, base::File::FLAG_OPEN | base::File::FLAG_READ); + if (!dir.IsValid()) + LOG(FATAL) << "corpus_dir " << dir_path << " could not be opened."; + + base::File::Info dir_info; + if (!dir.GetInfo(&dir_info)) + LOG(FATAL) << "Could not get corpus_dir " << dir_path << " file info."; + if (!dir_info.is_directory) + LOG(FATAL) << "corpus_dir " << dir_path << " is not a directory."; + } else { + LOG(INFO) << "corpus_dir not specified, writing serialized output to " + "stdout instead."; + } + + int last_index = 0; + for (int total = 0; total < num_entries; total++) { + SQLQueries queries = GenCorpusEntry(); + std::vector<std::string> queries_str; + for (int i = 0; i < queries.extra_queries_size(); i++) { + queries_str.push_back( + sql_fuzzer::SQLQueryToString(queries.extra_queries(i))); + if (to_stdout || getenv("LPM_DUMP_NATIVE_INPUT")) + std::cout << queries_str[i] << std::endl; + } + + if (getenv("PRINT_SQLITE_ERRORS")) + sql_fuzzer::RunSqlQueries(queries_str); + + // If we just want to print to stdout, skip the directory stuff below. + if (to_stdout) + continue; + + // It's okay to serialize without all required fields, as LPM uses + // ParsePartial* as well. + std::string proto_text; + if (!queries.SerializePartialToString(&proto_text)) + LOG(FATAL) << "Could not serialize queries to string."; + + bool found_file = false; + while (!found_file) { + base::FilePath file_path = + dir_path.Append("corpus_queries" + std::to_string(last_index)); + base::File file(file_path, + base::File::FLAG_CREATE | base::File::FLAG_WRITE); + if (file.created()) { + found_file = true; + if (file.Write(0, proto_text.data(), proto_text.length()) < 0) { + LOG(FATAL) << "Failed to write to file " << file_path; + } + } + last_index++; + } + } + + return 0; +}
diff --git a/third_party/sqlite/fuzz/sql_query_grammar.proto b/third_party/sqlite/fuzz/sql_query_grammar.proto index 2d6b90dd..ceb67799 100644 --- a/third_party/sqlite/fuzz/sql_query_grammar.proto +++ b/third_party/sqlite/fuzz/sql_query_grammar.proto
@@ -536,7 +536,7 @@ INSERT_OR_ROLLBACK = 3; INSERT_OR_ABORT = 4; INSERT_OR_FAIL = 5; - INSERT_IGNORE = 6; + INSERT_OR_IGNORE = 6; } required InsertType insert_type = 2; required SchemaTableAsAlias staa = 3; @@ -957,8 +957,8 @@ message LiteralValue { enum SpecialVal { VAL_NULL = 0; // using just "NULL" vauses it not to compile. - TRUE = 1; - FALSE = 2; + VAL_TRUE = 1; + VAL_FALSE = 2; CURRENT_TIME = 3; CURRENT_DATE = 4; CURRENT_TIMESTAMP = 5;
diff --git a/third_party/sqlite/fuzz/sql_query_proto_to_string.cc b/third_party/sqlite/fuzz/sql_query_proto_to_string.cc index c236f9f..9c4d224 100644 --- a/third_party/sqlite/fuzz/sql_query_proto_to_string.cc +++ b/third_party/sqlite/fuzz/sql_query_proto_to_string.cc
@@ -376,9 +376,13 @@ ret += '\''; return ret; case LitValType::kSpecialVal: - // special case for NULL + // special case for NULL, TRUE, FALSE if (lit_val.special_val() == LiteralValue::VAL_NULL) return "NULL"; + if (lit_val.special_val() == LiteralValue::VAL_TRUE) + return "TRUE"; + if (lit_val.special_val() == LiteralValue::VAL_FALSE) + return "FALSE"; // do not remove underscores return LiteralValue_SpecialVal_Name(lit_val.special_val()); case LitValType::kNumericLit: @@ -1425,7 +1429,7 @@ ret += " "; } ret += QualifiedTableNameToString(update.qtn()); - ret += " SET "; + ret += " "; ret += UpsertClausePart2ToString(update.ucp2()); return ret; } @@ -1524,7 +1528,7 @@ std::string ret; ret += TableOrSubqueryToString(jc.tos()); ret += " "; - for (int i = 1; i < jc.clauses_size(); i++) { + for (int i = 0; i < jc.clauses_size(); i++) { ret += JoinClauseCoreToString(jc.clauses(i)); } ret += " "; @@ -2409,12 +2413,12 @@ ret += if_exists; ret += schema; ret += IndexToString(d.index()); - } else if (d.has_index()) { + } else if (d.has_table()) { ret += "TABLE "; ret += if_exists; ret += schema; ret += TableToString(d.table()); - } else if (d.has_index()) { + } else if (d.has_trigger()) { ret += "TRIGGER "; ret += if_exists; ret += schema; @@ -2432,6 +2436,7 @@ CONV_FN(AlterTable, at) { std::string ret("ALTER TABLE "); ret += ExprSchemaTableToString(at.schema_table()); + ret += " "; if (at.has_col()) { ret += "RENAME "; if (at.column())
diff --git a/third_party/sqlite/fuzz/sql_query_proto_to_string.h b/third_party/sqlite/fuzz/sql_query_proto_to_string.h index 237f628..4664d74 100644 --- a/third_party/sqlite/fuzz/sql_query_proto_to_string.h +++ b/third_party/sqlite/fuzz/sql_query_proto_to_string.h
@@ -21,6 +21,8 @@ std::string StrftimeFnToString(const sql_query_grammar::StrftimeFn&); std::string ExprToString(const sql_query_grammar::Expr&); +std::string SQLQueryToString(const sql_query_grammar::SQLQuery&); + } // namespace sql_fuzzer #endif // THIRD_PARTY_SQLITE_FUZZ_SQL_QUERY_PROTO_TO_STRING_H_
diff --git a/third_party/sqlite/fuzz/sql_run_queries.cc b/third_party/sqlite/fuzz/sql_run_queries.cc index 6485c694..e0949d5 100644 --- a/third_party/sqlite/fuzz/sql_run_queries.cc +++ b/third_party/sqlite/fuzz/sql_run_queries.cc
@@ -13,8 +13,36 @@ namespace sql_fuzzer { namespace { +constexpr int kMaxNumRows = 10; +constexpr int kMaxNumColumns = 10; + +sqlite3_int64 killTime; + +/* Return the current real-world time in milliseconds since the +** Julian epoch (-4714-11-24). +*/ +static sqlite3_int64 timeOfDay(void) { + static sqlite3_vfs* clockVfs = 0; + sqlite3_int64 t; + if (clockVfs == 0) { + clockVfs = sqlite3_vfs_find(0); + if (clockVfs == 0) + return 0; + } + if (clockVfs->iVersion >= 2 && clockVfs->xCurrentTimeInt64 != 0) { + clockVfs->xCurrentTimeInt64(clockVfs, &t); + } else { + double r; + clockVfs->xCurrentTime(clockVfs, &r); + t = (sqlite3_int64)(r * 86400000.0); + } + return t; +} + int progress_handler(void*) { - return 1; + sqlite3_int64 iNow = timeOfDay(); + int rc = iNow >= killTime; + return rc; } } // namespace @@ -41,14 +69,6 @@ return nullptr; } -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - // Invoke the progress handler frequently to check to see if we - // are taking too long. The progress handler will return true - // (which will block further processing) if more than 10 seconds have - // elapsed since the start of the test. - sqlite3_progress_handler(db, 23, progress_handler, nullptr); -#endif - // Enables foreign key constraints sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, 1, &rc); @@ -83,10 +103,20 @@ // No sqlite3_bind. + // Reset progress callback for every query. Timeout after 1 second. + // ClusterFuzz timeouts are not useful, so we try to avoid them. + // This will hopefully make Clusterfuzz find better, smaller SELECT + // statements. +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + killTime = timeOfDay() + 1000; + sqlite3_progress_handler(db, 100, progress_handler, nullptr); +#endif + // Now run the compiled query. int col_cnt = sqlite3_column_count(stmt); + int count = 0; rc = SQLITE_ROW; - while (rc == SQLITE_ROW) { + while (rc == SQLITE_ROW && count++ <= kMaxNumRows) { rc = sqlite3_step(stmt); if (rc != SQLITE_DONE && rc != SQLITE_ROW) { if (getenv("PRINT_SQLITE_ERRORS")) { @@ -98,7 +128,7 @@ goto free_stmt; } // Loop through the columns to catch a little bit more coverage. - for (int i = 0; i < col_cnt; i++) { + for (int i = 0; i < col_cnt && i < kMaxNumColumns; i++) { switch (sqlite3_column_type(stmt, i)) { case SQLITE_INTEGER: sqlite3_column_int(stmt, i);
diff --git a/third_party/tcmalloc/README.chromium b/third_party/tcmalloc/README.chromium index 61ea99a..c23835f 100644 --- a/third_party/tcmalloc/README.chromium +++ b/third_party/tcmalloc/README.chromium
@@ -116,3 +116,4 @@ - Pulled several mipsel related changes from lss project to fix compile errors - Fixed line endings in vendor/README_windows.txt to Unix (LF) - Removed have_futex from spinlock_linux-inl.h; assume it's always there +- Add thread-safe support to query and update the heap sampling period
diff --git a/third_party/tcmalloc/chromium/src/sampler.cc b/third_party/tcmalloc/chromium/src/sampler.cc index e63d4cb..358b52c7 100644 --- a/third_party/tcmalloc/chromium/src/sampler.cc +++ b/third_party/tcmalloc/chromium/src/sampler.cc
@@ -35,30 +35,32 @@ #include "sampler.h" -#include <algorithm> // For min() #include <math.h> -#include "base/commandlineflags.h" +#include <algorithm> // For min() using std::min; +namespace tcmalloc { + // The approximate gap in bytes between sampling actions. // I.e., we take one sample approximately once every // tcmalloc_sample_parameter bytes of allocation // i.e. about once every 512KB if value is 1<<19. #ifdef NO_TCMALLOC_SAMPLES -DEFINE_int64(tcmalloc_sample_parameter, 0, - "Unused: code is compiled with NO_TCMALLOC_SAMPLES"); +std::atomic<size_t> Sampler::tcmalloc_sample_parameter_(0); #else -DEFINE_int64(tcmalloc_sample_parameter, - EnvToInt64("TCMALLOC_SAMPLE_PARAMETER", 0), - "The approximate gap in bytes between sampling actions. " - "This must be between 1 and 2^58."); +std::atomic<size_t> Sampler::tcmalloc_sample_parameter_( + EnvToInt64("TCMALLOC_SAMPLE_PARAMETER", 0)); #endif -namespace tcmalloc { +// Static +size_t Sampler::GetSamplePeriod() { + return tcmalloc_sample_parameter_.load(); +} -int Sampler::GetSamplePeriod() { - return FLAGS_tcmalloc_sample_parameter; +// Static +void Sampler::SetSamplePeriod(size_t period) { + tcmalloc_sample_parameter_.store(period); } // Run this before using your sampler @@ -89,7 +91,8 @@ // log_2(q) * (-log_e(2) * 1/m) = x // In the code, q is actually in the range 1 to 2**26, hence the -26 below ssize_t Sampler::PickNextSamplingPoint() { - if (FLAGS_tcmalloc_sample_parameter <= 0) { + size_t sampling_period = GetSamplePeriod(); + if (sampling_period == 0) { // In this case, we don't want to sample ever, and the larger a // value we put here, the longer until we hit the slow path // again. However, we have to support the flag changing at @@ -108,8 +111,7 @@ // under piii debug for some binaries. double q = static_cast<uint32_t>(rnd_ >> (prng_mod_power - 26)) + 1.0; // Put the computed p-value through the CDF of a geometric. - double interval = - (log2(q) - 26) * (-log(2.0) * FLAGS_tcmalloc_sample_parameter); + double interval = (log2(q) - 26) * (-log(2.0) * sampling_period); // Very large values of interval overflow ssize_t. If we happen to // hit such improbable condition, we simply cheat and clamp interval @@ -127,7 +129,7 @@ } } bytes_until_sample_ = PickNextSamplingPoint(); - return FLAGS_tcmalloc_sample_parameter <= 0; + return GetSamplePeriod() == 0; } } // namespace tcmalloc
diff --git a/third_party/tcmalloc/chromium/src/sampler.h b/third_party/tcmalloc/chromium/src/sampler.h index 16d3b09..735e4f00 100644 --- a/third_party/tcmalloc/chromium/src/sampler.h +++ b/third_party/tcmalloc/chromium/src/sampler.h
@@ -38,6 +38,7 @@ #include "config.h" #include <stddef.h> // for size_t +#include <atomic> #ifdef HAVE_STDINT_H #include <stdint.h> // for uint64_t, uint32_t, int32_t #endif @@ -122,11 +123,14 @@ // "escalate" to fuller and slower logic only if necessary. bool TryRecordAllocationFast(size_t k); - // Generate a geometric with mean 512K (or FLAG_tcmalloc_sample_parameter) + // Generate a geometric with mean tcmalloc_sample_parameter_. ssize_t PickNextSamplingPoint(); - // Returns the current sample period - static int GetSamplePeriod(); + // Returns the current sample period. + static size_t GetSamplePeriod(); + + // Updates the sample period. + static void SetSamplePeriod(size_t period); // The following are public for the purposes of testing static uint64_t NextRandom(uint64_t rnd_); // Returns the next prng value @@ -151,6 +155,7 @@ private: friend class SamplerTest; bool RecordAllocationSlow(size_t k); + static std::atomic<size_t> tcmalloc_sample_parameter_; }; inline bool Sampler::RecordAllocation(size_t k) {
diff --git a/third_party/tcmalloc/chromium/src/tcmalloc.cc b/third_party/tcmalloc/chromium/src/tcmalloc.cc index 328ea24..559082a 100644 --- a/third_party/tcmalloc/chromium/src/tcmalloc.cc +++ b/third_party/tcmalloc/chromium/src/tcmalloc.cc
@@ -126,6 +126,7 @@ #include "malloc_hook-inl.h" // for MallocHook::InvokeNewHook, etc #include "page_heap.h" // for PageHeap, PageHeap::Stats #include "page_heap_allocator.h" // for PageHeapAllocator +#include "sampler.h" // for Sampler #include "span.h" // for Span, DLL_Prepend, etc #include "stack_trace_table.h" // for StackTraceTable #include "static_vars.h" // for Static @@ -150,12 +151,13 @@ #include "libc_override.h" using tcmalloc::AlignmentForSize; -using tcmalloc::kLog; using tcmalloc::kCrash; using tcmalloc::kCrashWithStats; +using tcmalloc::kLog; using tcmalloc::Log; using tcmalloc::PageHeap; using tcmalloc::PageHeapAllocator; +using tcmalloc::Sampler; using tcmalloc::SizeMap; using tcmalloc::Span; using tcmalloc::StackTrace; @@ -658,7 +660,7 @@ // We may print an extra, tcmalloc-specific warning message here. virtual void GetHeapSample(MallocExtensionWriter* writer) { - if (FLAGS_tcmalloc_sample_parameter == 0) { + if (Sampler::GetSamplePeriod() == 0) { const char* const kWarningMsg = "%warn\n" "%warn This heap profile does not have any data in it, because\n" @@ -843,6 +845,11 @@ return true; } + if (strcmp(name, "tcmalloc.sampling_period_bytes") == 0) { + *value = Sampler::GetSamplePeriod(); + return true; + } + return false; } @@ -861,6 +868,11 @@ return true; } + if (strcmp(name, "tcmalloc.sampling_period_bytes") == 0) { + Sampler::SetSamplePeriod(value); + return true; + } + return false; }
diff --git a/third_party/tcmalloc/chromium/src/thread_cache.h b/third_party/tcmalloc/chromium/src/thread_cache.h index 94039b7..bc0ba93 100644 --- a/third_party/tcmalloc/chromium/src/thread_cache.h +++ b/third_party/tcmalloc/chromium/src/thread_cache.h
@@ -43,7 +43,6 @@ #include <stdint.h> // for uint32_t, uint64_t #endif #include <sys/types.h> // for ssize_t -#include "base/commandlineflags.h" #include "common.h" #include "free_list.h" // for FL_Pop, FL_PopRange, etc #include "internal_logging.h" // for ASSERT, etc @@ -53,8 +52,6 @@ #include "sampler.h" // for Sampler #include "static_vars.h" // for Static -DECLARE_int64(tcmalloc_sample_parameter); - namespace tcmalloc { //-------------------------------------------------------------------
diff --git a/tools/binary_size/supersize.pydeps b/tools/binary_size/supersize.pydeps index 96d974f..9765409 100644 --- a/tools/binary_size/supersize.pydeps +++ b/tools/binary_size/supersize.pydeps
@@ -29,9 +29,9 @@ ../grit/grit/node/__init__.py ../grit/grit/node/base.py ../grit/grit/node/include.py -../grit/grit/node/io.py ../grit/grit/node/message.py ../grit/grit/node/misc.py +../grit/grit/node/node_io.py ../grit/grit/node/structure.py ../grit/grit/node/variant.py ../grit/grit/pseudo.py
diff --git a/tools/grit/grit/format/html_inline_unittest.py b/tools/grit/grit/format/html_inline_unittest.py index 9a3077c4..eca6ada 100755 --- a/tools/grit/grit/format/html_inline_unittest.py +++ b/tools/grit/grit/format/html_inline_unittest.py
@@ -309,6 +309,7 @@ self.failUnlessEqual(resources, source_resources) self.failUnlessEqual(expected_inlined, util.FixLineEnd(result.inlined_data, '\n')) + tmp_dir.CleanUp() def testCssIncludedFileNames(self): '''Tests that all included files from css are returned''' @@ -398,6 +399,7 @@ self.failUnlessEqual(resources, source_resources) self.failUnlessEqual(expected_inlined, util.FixLineEnd(result.inlined_data, '\n')) + tmp_dir.CleanUp() def testFilenameVariableExpansion(self): '''Tests that variables are expanded in filenames before inlining.''' @@ -458,6 +460,7 @@ resources = result.inlined_files resources.add(tmp_dir.GetPath('index.html')) self.failUnlessEqual(resources, source_resources) + tmp_dir.CleanUp() def testWithCloseTags(self): '''Tests that close tags are removed.''' @@ -524,6 +527,7 @@ self.failUnlessEqual(resources, source_resources) self.failUnlessEqual(expected_inlined, util.FixLineEnd(result.inlined_data, '\n')) + tmp_dir.CleanUp() def testCommentedJsInclude(self): '''Tests that <include> works inside a comment.''' @@ -546,6 +550,7 @@ self.failUnlessEqual(resources, source_resources) self.failUnlessEqual(expected_inlined, util.FixLineEnd(result.inlined_data, '\n')) + tmp_dir.CleanUp() def testCommentedJsIf(self): '''Tests that <if> works inside a comment.''' @@ -586,6 +591,7 @@ self.failUnlessEqual(resources, source_resources) self.failUnlessEqual(expected_inlined, util.FixLineEnd(result.inlined_data, '\n')) + tmp_dir.CleanUp() def testImgSrcset(self): '''Tests that img srcset="" attributes are converted.''' @@ -640,6 +646,7 @@ self.failUnlessEqual(resources, source_resources) self.failUnlessEqual(expected_inlined, util.FixLineEnd(result.inlined_data, '\n')) + tmp_dir.CleanUp() def testConditionalInclude(self): '''Tests that output and dependency generation includes only files not'''\ @@ -717,6 +724,8 @@ actually_inlined = re.sub(r'\s+', ' ', util.FixLineEnd(result.inlined_data, '\n')) self.failUnlessEqual(expected_inlined, actually_inlined); + tmp_dir.CleanUp() + if __name__ == '__main__': unittest.main()
diff --git a/tools/grit/grit/format/rc_unittest.py b/tools/grit/grit/format/rc_unittest.py index a38001b1..497f315c 100755 --- a/tools/grit/grit/format/rc_unittest.py +++ b/tools/grit/grit/format/rc_unittest.py
@@ -36,13 +36,17 @@ self.type = type self.language = language self.file = file + def GetType(self): return self.type + def GetLanguage(self): return self.language + def GetOutputFilename(self): return self.file + class FormatRcUnittest(unittest.TestCase): def testMessages(self): root = util.ParseGrdForUnittest(''' @@ -74,7 +78,6 @@ IDS_WITH_LINEBREAKS "Good day sir,\\nI am a bee\\nSting sting" END''', output) - def testRcSection(self): root = util.ParseGrdForUnittest(''' <structures> @@ -228,7 +231,7 @@ # Check for removed "<if>" and "</if>" tags. self.failUnless(file_contents.find('<if expr=') == -1) self.failUnless(file_contents.find('</if>') == -1) - + os.remove(output_file) def testStructureNodeOutputfile(self): input_file = util.PathFromRoot('grit/testdata/simple.html') @@ -252,7 +255,7 @@ self.failUnless(contents.find('<p>') != -1) # should contain the markup self.failUnless(contents.find('Hello!') == -1) # should be translated - + os.remove(fr_file) def testChromeHtmlNodeOutputfile(self): input_file = util.PathFromRoot('grit/testdata/chrome_html.html') @@ -284,7 +287,7 @@ self.failUnless(file_contents.find('Hello Include!') != -1) # Check for inserted -webkit-image-set. self.failUnless(file_contents.find('content: -webkit-image-set') != -1) - + os.remove(output_file) def testSubstitutionHtml(self): input_file = util.PathFromRoot('grit/testdata/toolbar_about.html') @@ -311,7 +314,7 @@ contents = util.ReadFile(ar_file, util.RAW_TEXT) self.failUnless(contents.find('dir="RTL"') != -1) - + os.remove(ar_file) def testFallbackToEnglish(self): root = util.ParseGrdForUnittest('''\
diff --git a/tools/grit/grit/gather/admin_template_unittest.py b/tools/grit/grit/gather/admin_template_unittest.py index 6c7e56b..c63c08f 100755 --- a/tools/grit/grit/gather/admin_template_unittest.py +++ b/tools/grit/grit/gather/admin_template_unittest.py
@@ -96,22 +96,18 @@ def testFileIsOutput(self): grd = self.MakeGrd() - dirname = tempfile.mkdtemp() + dirname = util.TempDir({}) try: tool = build.RcBuilder() tool.o = grit_runner.Options() - tool.output_directory = dirname + tool.output_directory = dirname.GetPath() tool.res = grd tool.Process() - self.failUnless(os.path.isfile( - os.path.join(dirname, 'de_GoogleDesktop.adm'))) - self.failUnless(os.path.isfile( - os.path.join(dirname, 'de_README.txt'))) + self.failUnless(os.path.isfile(dirname.GetPath('de_GoogleDesktop.adm'))) + self.failUnless(os.path.isfile(dirname.GetPath('de_README.txt'))) finally: - for f in os.listdir(dirname): - os.unlink(os.path.join(dirname, f)) - os.rmdir(dirname) + dirname.CleanUp() if __name__ == '__main__': unittest.main()
diff --git a/tools/grit/grit/grd_reader_unittest.py b/tools/grit/grit/grd_reader_unittest.py index a6a80a0..7e98f80 100755 --- a/tools/grit/grit/grd_reader_unittest.py +++ b/tools/grit/grit/grd_reader_unittest.py
@@ -216,9 +216,8 @@ <grit-part> <message name="IDS_TEST5" desc="test5">test5</message> </grit-part>''' - arbitrary_path_grd_file = os.path.join( - util.TempDir({'arbitrary_path.grp': arbitrary_path_grd}).GetPath(), - 'arbitrary_path.grp') + tmp_dir = util.TempDir({'arbitrary_path.grp': arbitrary_path_grd}) + arbitrary_path_grd_file = tmp_dir.GetPath('arbitrary_path.grp') top_grd = u'''\ <grit latest_public_release="2" current_release="3"> <release seq="3"> @@ -271,20 +270,23 @@ </grit>''' % arbitrary_path_grd_file with util.TempDir({'sub.grp': sub_grd, - 'subsub.grp': subsub_grd}) as temp_dir: - output = grd_reader.Parse(StringIO.StringIO(top_grd), temp_dir.GetPath()) + 'subsub.grp': subsub_grd}) as tmp_sub_dir: + output = grd_reader.Parse(StringIO.StringIO(top_grd), + tmp_sub_dir.GetPath()) correct_sources = { 'IDS_TEST': None, - 'IDS_TEST2': temp_dir.GetPath('sub.grp'), - 'IDS_TEST3': temp_dir.GetPath('sub.grp'), - 'IDS_TEST4': temp_dir.GetPath('subsub.grp'), + 'IDS_TEST2': tmp_sub_dir.GetPath('sub.grp'), + 'IDS_TEST3': tmp_sub_dir.GetPath('sub.grp'), + 'IDS_TEST4': tmp_sub_dir.GetPath('subsub.grp'), 'IDS_TEST5': arbitrary_path_grd_file, } + for node in output.ActiveDescendants(): with node: if isinstance(node, message.MessageNode): self.assertEqual(correct_sources[node.attrs.get('name')], node.source) self.assertEqual(expected_output.split(), output.FormatXml().split()) + tmp_dir.CleanUp() def testPartInclusionFailure(self): template = u'''
diff --git a/tools/grit/grit/node/base_unittest.py b/tools/grit/grit/node/base_unittest.py index 58acdfb..556c7456 100755 --- a/tools/grit/grit/node/base_unittest.py +++ b/tools/grit/grit/node/base_unittest.py
@@ -186,8 +186,8 @@ </grit>''' grd = grd_reader.Parse(StringIO.StringIO(xml), util.PathFromRoot('grit/test/data')) - from grit.node import io - output_nodes = grd.GetChildrenOfType(io.OutputNode) + from grit.node import node_io + output_nodes = grd.GetChildrenOfType(node_io.OutputNode) self.failUnlessEqual(len(output_nodes), 3) self.failUnlessEqual(output_nodes[2].attrs['filename'], 'de/generated_resources.rc')
diff --git a/tools/grit/grit/node/empty.py b/tools/grit/grit/node/empty.py index f2a1a1e..b821752 100644 --- a/tools/grit/grit/node/empty.py +++ b/tools/grit/grit/node/empty.py
@@ -8,10 +8,10 @@ from grit.node import base from grit.node import include -from grit.node import structure from grit.node import message -from grit.node import io from grit.node import misc +from grit.node import node_io +from grit.node import structure class GroupingNode(base.Node): @@ -48,13 +48,13 @@ class TranslationsNode(base.Node): '''The <translations> element.''' def _IsValidChild(self, child): - return isinstance(child, (io.FileNode, misc.IfNode, misc.PartNode)) + return isinstance(child, (node_io.FileNode, misc.IfNode, misc.PartNode)) class OutputsNode(base.Node): '''The <outputs> element.''' def _IsValidChild(self, child): - return isinstance(child, (io.OutputNode, misc.IfNode, misc.PartNode)) + return isinstance(child, (node_io.OutputNode, misc.IfNode, misc.PartNode)) class IdentifiersNode(GroupingNode):
diff --git a/tools/grit/grit/node/include.py b/tools/grit/grit/node/include.py index 7699b68c..667ee61 100644 --- a/tools/grit/grit/node/include.py +++ b/tools/grit/grit/node/include.py
@@ -30,12 +30,13 @@ def _IsValidChild(self, child): return False - def _GetFlattenedData(self, allow_external_script=False): + def _GetFlattenedData( + self, allow_external_script=False, preprocess_only=False): if not self._flattened_data: filename = self.ToRealPath(self.GetInputPath()) self._flattened_data = ( grit.format.html_inline.InlineToString(filename, self, - preprocess_only=False, + preprocess_only=preprocess_only, allow_external_script=allow_external_script)) return self._flattened_data def MandatoryAttributes(self): @@ -95,6 +96,8 @@ if self.attrs['flattenhtml'] == 'true': allow_external_script = self.attrs['allowexternalscript'] == 'true' data = self._GetFlattenedData(allow_external_script=allow_external_script) + elif self.attrs['preprocess'] == 'true': + data = self._GetFlattenedData(preprocess_only=True) else: data = util.ReadFile(filename, util.BINARY)
diff --git a/tools/grit/grit/node/include_unittest.py b/tools/grit/grit/node/include_unittest.py index a97a26e8..cef8c09 100755 --- a/tools/grit/grit/node/include_unittest.py +++ b/tools/grit/grit/node/include_unittest.py
@@ -101,13 +101,10 @@ preprocess="true" type="chrome_html"/> </includes>''', base_dir = util.PathFromRoot('grit/testdata')) inc, = root.GetChildrenOfType(include.IncludeNode) - temp_dir = util.TempDir({}) - output_file = inc.Process(temp_dir.GetPath()) - result = open(temp_dir.GetPath(output_file)).read() + result = inc.GetDataPackValue(lang='en', encoding=1) self.failUnless(result.find('should be kept') != -1) self.failUnless(result.find('in the middle...') != -1) self.failUnless(result.find('should be removed') == -1) - temp_dir.CleanUp() if __name__ == '__main__':
diff --git a/tools/grit/grit/node/mapping.py b/tools/grit/grit/node/mapping.py index 659f0e0..083f77b 100644 --- a/tools/grit/grit/node/mapping.py +++ b/tools/grit/grit/node/mapping.py
@@ -10,12 +10,12 @@ from grit import exception from grit.node import empty +from grit.node import include from grit.node import message from grit.node import misc -from grit.node import variant +from grit.node import node_io from grit.node import structure -from grit.node import include -from grit.node import io +from grit.node import variant _ELEMENT_TO_CLASS = { @@ -26,9 +26,9 @@ 'structures' : empty.StructuresNode, 'translations' : empty.TranslationsNode, 'include' : include.IncludeNode, - 'emit' : io.EmitNode, - 'file' : io.FileNode, - 'output' : io.OutputNode, + 'emit' : node_io.EmitNode, + 'file' : node_io.FileNode, + 'output' : node_io.OutputNode, 'ex' : message.ExNode, 'message' : message.MessageNode, 'ph' : message.PhNode,
diff --git a/tools/grit/grit/node/message_unittest.py b/tools/grit/grit/node/message_unittest.py index 3592af37..9e235683 100755 --- a/tools/grit/grit/node/message_unittest.py +++ b/tools/grit/grit/node/message_unittest.py
@@ -12,11 +12,7 @@ import StringIO if __name__ == '__main__': - # When executed as the main module, the first entry in sys.path will be - # the directory contain this module. This entry causes the io.py file in this - # directory to be selected whenever any file does "import io", rather than the - # system "io" module. As a work-around, remove the first sys.path entry. - sys.path[0] = os.path.join(os.path.dirname(__file__), '../..') + sys.path.append(os.path.join(os.path.dirname(__file__), '../..')) from grit import tclib from grit import util
diff --git a/tools/grit/grit/node/misc.py b/tools/grit/grit/node/misc.py index 2d561aa..5d983ee9 100644 --- a/tools/grit/grit/node/misc.py +++ b/tools/grit/grit/node/misc.py
@@ -15,8 +15,8 @@ from grit.extern import FP import grit.format.rc_header from grit.node import base -from grit.node import io from grit.node import message +from grit.node import node_io # RTL languages @@ -455,7 +455,7 @@ self.SetFallbackToDefaultLayout(fallback) for node in self.ActiveDescendants(): - if isinstance(node, (io.FileNode, include.IncludeNode, + if isinstance(node, (node_io.FileNode, include.IncludeNode, structure.StructureNode, variant.SkeletonNode)): input_path = node.GetInputPath() if input_path is not None:
diff --git a/tools/grit/grit/node/io.py b/tools/grit/grit/node/node_io.py similarity index 98% rename from tools/grit/grit/node/io.py rename to tools/grit/grit/node/node_io.py index 0e17717e..99423ad1 100644 --- a/tools/grit/grit/node/io.py +++ b/tools/grit/grit/node/node_io.py
@@ -7,8 +7,6 @@ import os -import grit.format.rc_header - from grit import xtb_reader from grit.node import base
diff --git a/tools/grit/grit/node/io_unittest.py b/tools/grit/grit/node/node_io_unittest.py similarity index 97% rename from tools/grit/grit/node/io_unittest.py rename to tools/grit/grit/node/node_io_unittest.py index 7409b67..f82887e 100755 --- a/tools/grit/grit/node/io_unittest.py +++ b/tools/grit/grit/node/node_io_unittest.py
@@ -3,19 +3,18 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -'''Unit tests for io.FileNode''' +'''Unit tests for node_io.FileNode''' +import StringIO import os import sys +import unittest + if __name__ == '__main__': sys.path.append(os.path.join(os.path.dirname(__file__), '../..')) -import os -import StringIO -import unittest - from grit.node import misc -from grit.node import io +from grit.node import node_io from grit.node import empty from grit import grd_reader from grit import util @@ -31,7 +30,7 @@ translations = empty.TranslationsNode() translations.StartParsing(u'translations', root) root.AddChild(translations) - file_node = io.FileNode() + file_node = node_io.FileNode() file_node.StartParsing(u'file', translations) file_node.HandleAttribute(u'path', ur'flugel\kugel.pdf') translations.AddChild(file_node) @@ -137,7 +136,7 @@ defines={}) grd.SetOutputLanguage('en') grd.RunGatherers() - outputs = grd.GetChildrenOfType(io.OutputNode) + outputs = grd.GetChildrenOfType(node_io.OutputNode) active = set(grd.ActiveDescendants()) self.failUnless(outputs[0] in active) self.failUnless(outputs[0].GetType() == 'rc_header')
diff --git a/tools/grit/grit/node/structure_unittest.py b/tools/grit/grit/node/structure_unittest.py index 2da15ed9..19b9d6f 100755 --- a/tools/grit/grit/node/structure_unittest.py +++ b/tools/grit/grit/node/structure_unittest.py
@@ -56,7 +56,8 @@ grd.RunGatherers() node, = grd.GetChildrenOfType(structure.StructureNode) filename = node.Process(tempfile.gettempdir()) - with open(os.path.join(tempfile.gettempdir(), filename)) as f: + filepath = os.path.join(tempfile.gettempdir(), filename) + with open(filepath) as f: result = f.read() self.failUnlessEqual(('<h1>Hello!</h1>\n' 'Some cool things are foo, bar, baz.\n' @@ -64,6 +65,7 @@ '<p>\n' ' Hello!\n' '</p>\n'), result) + os.remove(filepath) def testCompressGzip(self): test_data_root = util.PathFromRoot('grit/testdata')
diff --git a/tools/grit/grit/test_suite_all.py b/tools/grit/grit/test_suite_all.py index db66bb4..bc5e4e3 100755 --- a/tools/grit/grit/test_suite_all.py +++ b/tools/grit/grit/test_suite_all.py
@@ -50,12 +50,12 @@ import grit.gather.tr_html_unittest import grit.gather.txt_unittest import grit.node.base_unittest - import grit.node.io_unittest + import grit.node.custom.filename_unittest import grit.node.include_unittest import grit.node.message_unittest import grit.node.misc_unittest - import grit.node.structure_unittest # - import grit.node.custom.filename_unittest + import grit.node.node_io_unittest + import grit.node.structure_unittest import grit.tool.android2grd_unittest import grit.tool.build_unittest import grit.tool.buildinfo_unittest @@ -95,14 +95,14 @@ grit.gather.tr_html_unittest.TrHtmlUnittest, grit.gather.txt_unittest.TxtUnittest, grit.node.base_unittest.NodeUnittest, - grit.node.io_unittest.FileNodeUnittest, + grit.node.custom.filename_unittest.WindowsFilenameUnittest, grit.node.include_unittest.IncludeNodeUnittest, grit.node.message_unittest.MessageUnittest, grit.node.misc_unittest.GritNodeUnittest, grit.node.misc_unittest.IfNodeUnittest, grit.node.misc_unittest.ReleaseNodeUnittest, + grit.node.node_io_unittest.FileNodeUnittest, grit.node.structure_unittest.StructureUnittest, - grit.node.custom.filename_unittest.WindowsFilenameUnittest, grit.tool.android2grd_unittest.Android2GrdUnittest, grit.tool.build_unittest.BuildUnittest, grit.tool.buildinfo_unittest.BuildInfoUnittest,
diff --git a/tools/grit/grit/tool/android2grd.py b/tools/grit/grit/tool/android2grd.py index 4326209..dd47fda 100644 --- a/tools/grit/grit/tool/android2grd.py +++ b/tools/grit/grit/tool/android2grd.py
@@ -13,7 +13,7 @@ import xml.dom.minidom import grit.node.empty -from grit.node import io +from grit.node import node_io from grit.node import message from grit.tool import interface @@ -403,7 +403,7 @@ """ xtb_file = os.path.normpath(os.path.join( self.xtb_dir, '%s_%s.xtb' % (self.name, lang))) - fnode = io.FileNode() + fnode = node_io.FileNode() fnode.StartParsing(u'file', translations_node) fnode.HandleAttribute('path', xtb_file) fnode.HandleAttribute('lang', lang) @@ -414,11 +414,11 @@ def __CreateCppHeaderOutputNode(self, outputs_node, header_dir): """Creates the <output> element corresponding to the generated c header.""" header_file_name = os.path.join(header_dir, self.name + '.h') - header_node = io.OutputNode() + header_node = node_io.OutputNode() header_node.StartParsing(u'output', outputs_node) header_node.HandleAttribute('filename', header_file_name) header_node.HandleAttribute('type', 'rc_header') - emit_node = io.EmitNode() + emit_node = node_io.EmitNode() emit_node.StartParsing(u'emit', header_node) emit_node.HandleAttribute('emit_type', 'prepend') emit_node.EndParsing() @@ -431,7 +431,7 @@ """Creates the <output> element corresponding to various rc file output.""" rc_file_name = self.name + '_' + lang + ".rc" rc_path = os.path.join(rc_dir, rc_file_name) - node = io.OutputNode() + node = node_io.OutputNode() node.StartParsing(u'output', outputs_node) node.HandleAttribute('filename', rc_path) node.HandleAttribute('lang', lang) @@ -459,7 +459,7 @@ xml_path = os.path.normpath(os.path.join( xml_res_dir, values, 'strings.xml')) - node = io.OutputNode() + node = node_io.OutputNode() node.StartParsing(u'output', outputs_node) node.HandleAttribute('filename', xml_path) node.HandleAttribute('lang', locale)
diff --git a/tools/grit/grit/tool/android2grd_unittest.py b/tools/grit/grit/tool/android2grd_unittest.py index 51186163..0c7ed54a 100755 --- a/tools/grit/grit/tool/android2grd_unittest.py +++ b/tools/grit/grit/tool/android2grd_unittest.py
@@ -16,9 +16,9 @@ from grit import grd_reader from grit import util from grit.node import empty -from grit.node import io from grit.node import message from grit.node import misc +from grit.node import node_io from grit.tool import android2grd @@ -99,7 +99,7 @@ # Check that the structure of the GritNode is as expected. messages = grd.GetChildrenOfType(message.MessageNode) translations = grd.GetChildrenOfType(empty.TranslationsNode) - files = grd.GetChildrenOfType(io.FileNode) + files = grd.GetChildrenOfType(node_io.FileNode) self.assertEqual(len(translations), 1) self.assertEqual(len(files), 3) @@ -123,7 +123,7 @@ def testTranslations(self): grd = self.__ParseAndroidXml(['--languages', 'en-US,en-GB,ru,id']) - files = grd.GetChildrenOfType(io.FileNode) + files = grd.GetChildrenOfType(node_io.FileNode) us_file = filter(lambda x: x.attrs['lang'] == 'en-US', files) self.assertTrue(us_file) self.assertEqual(us_file[0].GetInputPath(), @@ -141,7 +141,7 @@ '--xtb-dir', 'xtb/dir', '--xml-dir', 'xml/dir']) - outputs = grd.GetChildrenOfType(io.OutputNode) + outputs = grd.GetChildrenOfType(node_io.OutputNode) self.assertEqual(len(outputs), 7) header_outputs = filter(lambda x: x.GetType() == 'rc_header', outputs) @@ -153,7 +153,7 @@ self.assertEqual(len(xml_outputs), 3) # The header node should have an "<emit>" child and the proper filename. - self.assertTrue(header_outputs[0].GetChildrenOfType(io.EmitNode)) + self.assertTrue(header_outputs[0].GetChildrenOfType(node_io.EmitNode)) self.assertEqual(util.normpath(header_outputs[0].GetFilename()), util.normpath('header/dir/chrome_android_strings.h'))
diff --git a/tools/grit/grit/tool/build_unittest.py b/tools/grit/grit/tool/build_unittest.py index 7dad441..985882c 100755 --- a/tools/grit/grit/tool/build_unittest.py +++ b/tools/grit/grit/tool/build_unittest.py
@@ -34,26 +34,27 @@ # This is a regression test; we had a bug where GRIT would fail to find # messages with substitutions e.g. "Hello [IDS_USER]" where IDS_USER is # another <message>. - output_dir = tempfile.mkdtemp() + output_dir = util.TempDir({}) builder = build.RcBuilder() class DummyOpts(object): def __init__(self): self.input = util.PathFromRoot('grit/testdata/substitute.grd') self.verbose = False self.extra_verbose = False - builder.Run(DummyOpts(), ['-o', output_dir]) + builder.Run(DummyOpts(), ['-o', output_dir.GetPath()]) + output_dir.CleanUp() def testGenerateDepFile(self): - output_dir = tempfile.mkdtemp() + output_dir = util.TempDir({}) builder = build.RcBuilder() class DummyOpts(object): def __init__(self): self.input = util.PathFromRoot('grit/testdata/depfile.grd') self.verbose = False self.extra_verbose = False - expected_dep_file = os.path.join(output_dir, 'substitute.grd.d') - builder.Run(DummyOpts(), ['-o', output_dir, - '--depdir', output_dir, + expected_dep_file = output_dir.GetPath('substitute.grd.d') + builder.Run(DummyOpts(), ['-o', output_dir.GetPath(), + '--depdir', output_dir.GetPath(), '--depfile', expected_dep_file]) self.failUnless(os.path.isfile(expected_dep_file)) @@ -68,21 +69,22 @@ util.PathFromRoot('grit/testdata/grit_part.grdp'), util.PathFromRoot('grit/testdata/special_100_percent/a.png'), ]) + output_dir.CleanUp() def testGenerateDepFileWithResourceIds(self): - output_dir = tempfile.mkdtemp() + output_dir = util.TempDir({}) builder = build.RcBuilder() class DummyOpts(object): def __init__(self): self.input = util.PathFromRoot('grit/testdata/substitute_no_ids.grd') self.verbose = False self.extra_verbose = False - expected_dep_file = os.path.join(output_dir, 'substitute_no_ids.grd.d') + expected_dep_file = output_dir.GetPath('substitute_no_ids.grd.d') builder.Run(DummyOpts(), ['-f', util.PathFromRoot('grit/testdata/resource_ids'), - '-o', output_dir, - '--depdir', output_dir, - '--depfile', expected_dep_file]) + '-o', output_dir.GetPath(), + '--depdir', output_dir.GetPath(), + '--depfile', expected_dep_file]) self.failUnless(os.path.isfile(expected_dep_file)) with open(expected_dep_file) as f: @@ -96,9 +98,10 @@ util.PathFromRoot('grit/testdata/substitute.xmb')) self.failUnlessEqual(deps[1], util.PathFromRoot('grit/testdata/resource_ids')) + output_dir.CleanUp() def testAssertOutputs(self): - output_dir = tempfile.mkdtemp() + output_dir = util.TempDir({}) class DummyOpts(object): def __init__(self): self.input = util.PathFromRoot('grit/testdata/substitute.grd') @@ -109,24 +112,24 @@ builder_fail = build.RcBuilder() self.failUnlessEqual(2, builder_fail.Run(DummyOpts(), [ - '-o', output_dir, + '-o', output_dir.GetPath(), '-a', os.path.abspath( - os.path.join(output_dir, 'en_generated_resources.rc'))])) + output_dir.GetPath('en_generated_resources.rc'))])) # Complete output file list should succeed. builder_ok = build.RcBuilder() self.failUnlessEqual(0, builder_ok.Run(DummyOpts(), [ - '-o', output_dir, + '-o', output_dir.GetPath(), '-a', os.path.abspath( - os.path.join(output_dir, 'en_generated_resources.rc')), + output_dir.GetPath('en_generated_resources.rc')), '-a', os.path.abspath( - os.path.join(output_dir, 'sv_generated_resources.rc')), - '-a', os.path.abspath( - os.path.join(output_dir, 'resource.h'))])) + output_dir.GetPath('sv_generated_resources.rc')), + '-a', os.path.abspath(output_dir.GetPath('resource.h'))])) + output_dir.CleanUp() def testAssertTemplateOutputs(self): - output_dir = tempfile.mkdtemp() + output_dir = util.TempDir({}) class DummyOpts(object): def __init__(self): self.input = util.PathFromRoot('grit/testdata/substitute_tmpl.grd') @@ -137,23 +140,20 @@ builder_fail = build.RcBuilder() self.failUnlessEqual(2, builder_fail.Run(DummyOpts(), [ - '-o', output_dir, + '-o', output_dir.GetPath(), '-E', 'name=foo', - '-a', os.path.abspath( - os.path.join(output_dir, 'en_foo_resources.rc'))])) + '-a', os.path.abspath(output_dir.GetPath('en_foo_resources.rc'))])) # Complete output file list should succeed. builder_ok = build.RcBuilder() self.failUnlessEqual(0, builder_ok.Run(DummyOpts(), [ - '-o', output_dir, + '-o', output_dir.GetPath(), '-E', 'name=foo', - '-a', os.path.abspath( - os.path.join(output_dir, 'en_foo_resources.rc')), - '-a', os.path.abspath( - os.path.join(output_dir, 'sv_foo_resources.rc')), - '-a', os.path.abspath( - os.path.join(output_dir, 'resource.h'))])) + '-a', os.path.abspath(output_dir.GetPath('en_foo_resources.rc')), + '-a', os.path.abspath(output_dir.GetPath('sv_foo_resources.rc')), + '-a', os.path.abspath(output_dir.GetPath('resource.h'))])) + output_dir.CleanUp() def _verifyWhitelistedOutput(self, filename, @@ -187,7 +187,7 @@ self.assertFalse(non_whitelisted_ids_found, non_whitelisted_msg) def testWhitelistStrings(self): - output_dir = tempfile.mkdtemp() + output_dir = util.TempDir({}) builder = build.RcBuilder() class DummyOpts(object): def __init__(self): @@ -195,10 +195,10 @@ self.verbose = False self.extra_verbose = False whitelist_file = util.PathFromRoot('grit/testdata/whitelist.txt') - builder.Run(DummyOpts(), ['-o', output_dir, + builder.Run(DummyOpts(), ['-o', output_dir.GetPath(), '-w', whitelist_file]) - header = os.path.join(output_dir, 'whitelist_test_resources.h') - rc = os.path.join(output_dir, 'en_whitelist_test_strings.rc') + header = output_dir.GetPath('whitelist_test_resources.h') + rc = output_dir.GetPath('en_whitelist_test_strings.rc') whitelisted_ids = ['IDS_MESSAGE_WHITELISTED'] non_whitelisted_ids = ['IDS_MESSAGE_NOT_WHITELISTED'] @@ -213,9 +213,10 @@ non_whitelisted_ids, encoding='utf16' ) + output_dir.CleanUp() def testWhitelistResources(self): - output_dir = tempfile.mkdtemp() + output_dir = util.TempDir({}) builder = build.RcBuilder() class DummyOpts(object): def __init__(self): @@ -223,12 +224,12 @@ self.verbose = False self.extra_verbose = False whitelist_file = util.PathFromRoot('grit/testdata/whitelist.txt') - builder.Run(DummyOpts(), ['-o', output_dir, + builder.Run(DummyOpts(), ['-o', output_dir.GetPath(), '-w', whitelist_file]) - header = os.path.join(output_dir, 'whitelist_test_resources.h') - map_cc = os.path.join(output_dir, 'whitelist_test_resources_map.cc') - map_h = os.path.join(output_dir, 'whitelist_test_resources_map.h') - pak = os.path.join(output_dir, 'whitelist_test_resources.pak') + header = output_dir.GetPath('whitelist_test_resources.h') + map_cc = output_dir.GetPath('whitelist_test_resources_map.cc') + map_h = output_dir.GetPath('whitelist_test_resources_map.h') + pak = output_dir.GetPath('whitelist_test_resources.pak') # Ensure the resource map header and .pak files exist, but don't verify # their content. @@ -253,9 +254,10 @@ whitelisted_ids, non_whitelisted_ids, ) + output_dir.CleanUp() def testWriteOnlyNew(self): - output_dir = tempfile.mkdtemp() + output_dir = util.TempDir({}) builder = build.RcBuilder() class DummyOpts(object): def __init__(self): @@ -263,27 +265,30 @@ self.verbose = False self.extra_verbose = False UNCHANGED = 10 - header = os.path.join(output_dir, 'resource.h') + header = output_dir.GetPath('resource.h') - builder.Run(DummyOpts(), ['-o', output_dir]) + builder.Run(DummyOpts(), ['-o', output_dir.GetPath()]) self.failUnless(os.path.exists(header)) first_mtime = os.stat(header).st_mtime os.utime(header, (UNCHANGED, UNCHANGED)) - builder.Run(DummyOpts(), ['-o', output_dir, '--write-only-new', '0']) + builder.Run(DummyOpts(), + ['-o', output_dir.GetPath(), '--write-only-new', '0']) self.failUnless(os.path.exists(header)) second_mtime = os.stat(header).st_mtime os.utime(header, (UNCHANGED, UNCHANGED)) - builder.Run(DummyOpts(), ['-o', output_dir, '--write-only-new', '1']) + builder.Run(DummyOpts(), + ['-o', output_dir.GetPath(), '--write-only-new', '1']) self.failUnless(os.path.exists(header)) third_mtime = os.stat(header).st_mtime self.assertTrue(abs(second_mtime - UNCHANGED) > 5) self.assertTrue(abs(third_mtime - UNCHANGED) < 5) + output_dir.CleanUp() def testGenerateDepFileWithDependOnStamp(self): - output_dir = tempfile.mkdtemp() + output_dir = util.TempDir({}) builder = build.RcBuilder() class DummyOpts(object): def __init__(self): @@ -292,12 +297,12 @@ self.extra_verbose = False expected_dep_file_name = 'substitute.grd.d' expected_stamp_file_name = expected_dep_file_name + '.stamp' - expected_dep_file = os.path.join(output_dir, expected_dep_file_name) - expected_stamp_file = os.path.join(output_dir, expected_stamp_file_name) + expected_dep_file = output_dir.GetPath(expected_dep_file_name) + expected_stamp_file = output_dir.GetPath(expected_stamp_file_name) if os.path.isfile(expected_stamp_file): os.remove(expected_stamp_file) - builder.Run(DummyOpts(), ['-o', output_dir, - '--depdir', output_dir, + builder.Run(DummyOpts(), ['-o', output_dir.GetPath(), + '--depdir', output_dir.GetPath(), '--depfile', expected_dep_file, '--depend-on-stamp']) self.failUnless(os.path.isfile(expected_stamp_file)) @@ -307,8 +312,8 @@ OLDTIME = 10 os.utime(expected_stamp_file, (OLDTIME, OLDTIME)) - builder.Run(DummyOpts(), ['-o', output_dir, - '--depdir', output_dir, + builder.Run(DummyOpts(), ['-o', output_dir.GetPath(), + '--depdir', output_dir.GetPath(), '--depfile', expected_dep_file, '--depend-on-stamp']) self.failUnless(os.path.isfile(expected_stamp_file)) @@ -328,6 +333,7 @@ self.failUnlessEqual(deps, [ util.PathFromRoot('grit/testdata/substitute.xmb'), ]) + output_dir.CleanUp() if __name__ == '__main__':
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index f729c9b8..04cec24 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -198,7 +198,7 @@ 'chromeos-amd64-generic-rel-goma-canary': 'cros_chrome_sdk', 'chromeos-amd64-generic-rel-vm-tests': 'cros_chrome_sdk_headless_ozone_dcheck_always_on', - 'chromeos-kevin-rel-hw-tests': 'cros_chrome_sdk_headless_ozone_dcheck_always_on', + 'chromeos-kevin-rel-hw-tests': 'cros_chrome_sdk_headless_ozone', 'Linux Builder Goma Canary': 'release_bot', 'Linux Builder Goma Latest Client': 'release_bot', @@ -264,7 +264,6 @@ 'Linux Viz': 'release_trybot', 'linux-annotator-rel': 'release_bot', 'linux-autofill-captured-sites-rel': 'release_bot', - 'linux-gtest-hackathon-dbg': 'debug_bot', 'linux-blink-animation-use-time-delta': 'debug_bot_enable_blink_animation_use_time_delta', 'linux-blink-heap-incremental-marking': 'debug_bot_enable_blink_heap_incremental_marking', 'linux-blink-heap-verification': 'release_bot_enable_blink_heap_verification_dcheck_always_on', @@ -1909,7 +1908,7 @@ 'enable_websockets=false use_platform_icu_alternatives=true ' 'use_partition_alloc=false enable_reporting=true ' 'include_transport_security_state_preload_list=false ' - 'use_crash_key_stubs=true ' + 'use_crash_key_stubs=true use_hashed_jni_names=true ' 'clang_use_default_sample_profile=false ' 'enable_resource_whitelist_generation=false'), },
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index a993bbd6..b74e3bf 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -8004,6 +8004,12 @@ <int value="6" label="Articles"/> </enum> +<enum name="ContentSuggestionsDisplayStatus"> + <int value="0" label="Visible"/> + <int value="1" label="Collapsed"/> + <int value="2" label="Disabled by policy"/> +</enum> + <enum name="ContentSuggestionsNotificationsAction"> <int value="0" label="Tap"/> <int value="1" label="Dismissal"/> @@ -21072,6 +21078,69 @@ <int value="2661" label="NavigatorPlatform"/> <int value="2662" label="NavigatorPlugins"/> <int value="2663" label="NavigatorUserAgent"/> + <int value="2664" label="WebBluetoothRequestScan"/> + <int value="2665" label="V8SVGGeometryElement_IsPointInFill_Method"/> + <int value="2666" label="V8SVGGeometryElement_IsPointInStroke_Method"/> + <int value="2667" label="V8SVGGeometryElement_GetTotalLength_Method"/> + <int value="2668" label="V8SVGGeometryElement_GetPointAtLength_Method"/> + <int value="2669" label="OffscreenCanvasTransferToImageBitmap"/> + <int value="2670" label="OffscreenCanvasIsPointInPath"/> + <int value="2671" label="OffscreenCanvasIsPointInStroke"/> + <int value="2672" label="OffscreenCanvasMeasureText"/> + <int value="2673" label="OffscreenCanvasGetImageData"/> + <int value="2674" + label="V8SVGTextContentElement_GetComputedTextLength_Method"/> + <int value="2675" + label="V8SVGTextContentElement_GetEndPositionOfChar_Method"/> + <int value="2676" label="V8SVGTextContentElement_GetExtentOfChar_Method"/> + <int value="2677" + label="V8SVGTextContentElement_GetStartPositionOfChar_Method"/> + <int value="2678" label="V8SVGTextContentElement_GetSubStringLength_Method"/> + <int value="2679" label="V8BatteryManager_ChargingTime_AttributeGetter"/> + <int value="2680" label="V8BatteryManager_Charging_AttributeGetter"/> + <int value="2681" label="V8BatteryManager_DischargingTime_AttributeGetter"/> + <int value="2682" label="V8BatteryManager_Level_AttributeGetter"/> + <int value="2683" label="V8PaintRenderingContext2D_IsPointInPath_Method"/> + <int value="2684" label="V8PaintRenderingContext2D_IsPointInStroke_Method"/> + <int value="2685" label="V8PaymentRequest_CanMakePayment_Method"/> + <int value="2686" label="V8AnalyserNode_GetByteFrequencyData_Method"/> + <int value="2687" label="V8AnalyserNode_GetByteTimeDomainData_Method"/> + <int value="2688" label="V8AnalyserNode_GetFloatFrequencyData_Method"/> + <int value="2689" label="V8AnalyserNode_GetFloatTimeDomainData_Method"/> + <int value="2690" label="V8AudioBuffer_CopyFromChannel_Method"/> + <int value="2691" label="V8AudioBuffer_GetChannelData_Method"/> + <int value="2692" label="WebGLDebugRendererInfo"/> + <int value="2693" + label="V8WebGL2ComputeRenderingContext_GetExtension_Method"/> + <int value="2694" + label="V8WebGL2ComputeRenderingContext_GetSupportedExtensions_Method"/> + <int value="2695" label="V8WebGL2RenderingContext_GetExtension_Method"/> + <int value="2696" + label="V8WebGL2RenderingContext_GetSupportedExtensions_Method"/> + <int value="2697" label="V8WebGLRenderingContext_GetExtension_Method"/> + <int value="2698" + label="V8WebGLRenderingContext_GetSupportedExtensions_Method"/> + <int value="2699" label="V8Screen_AvailHeight_AttributeGetter"/> + <int value="2700" label="V8Screen_AvailWidth_AttributeGetter"/> + <int value="2701" label="V8Screen_ColorDepth_AttributeGetter"/> + <int value="2702" label="V8Screen_Height_AttributeGetter"/> + <int value="2703" label="V8Screen_PixelDepth_AttributeGetter"/> + <int value="2704" label="V8Screen_Width_AttributeGetter"/> + <int value="2705" label="WindowInnerWidth"/> + <int value="2706" label="WindowInnerHeight"/> + <int value="2707" label="V8Window_MatchMedia_Method"/> + <int value="2708" label="WindowScrollX"/> + <int value="2709" label="WindowScrollY"/> + <int value="2710" label="WindowPageXOffset"/> + <int value="2711" label="WindowPageYOffset"/> + <int value="2712" label="WindowScreenX"/> + <int value="2713" label="WindowScreenY"/> + <int value="2714" label="WindowOuterHeight"/> + <int value="2715" label="WindowOuterWidth"/> + <int value="2716" label="WindowDevicePixelRatio"/> + <int value="2717" label="CanvasCaptureStream"/> + <int value="2718" label="V8HTMLMediaElement_CanPlayType_Method"/> + <int value="2719" label="HistoryLength"/> </enum> <enum name="FeaturePolicyFeature"> @@ -52945,6 +53014,7 @@ <enum name="VAVDADecoderFailure"> <int value="0" label="VAAPI_ERROR"/> + <int value="1" label="VAAPI_VPP_ERROR"/> </enum> <enum name="VAVDAH264DecoderFailure">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index c16efb1..f791073 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -16432,6 +16432,18 @@ </summary> </histogram> +<histogram name="ContentSuggestions.Feed.DisplayStatusOnOpen" + enum="ContentSuggestionsDisplayStatus" expires_after="2019-12-01"> + <owner>gangwu@chromium.org</owner> + <owner>fgorski@chromium.org</owner> + <summary> + Android: The display status of the content suggestions when users open NTPs. + Whether content suggestions are disabled by policy (e.g. enterprise or + supervised users), enabled but collapsed, or enabled and expanded when a new + NTP is created. + </summary> +</histogram> + <histogram name="ContentSuggestions.Feed.Image.FetchResult" enum="FeedImageFetchResult" expires_after="2019-10-01"> <owner>wylieb@chromium.org</owner> @@ -16592,6 +16604,17 @@ </summary> </histogram> +<histogram name="ContentSuggestions.Feed.PagePopulatingTime" units="ms" + expires_after="2019-12-01"> + <owner>gangwu@chromium.org</owner> + <owner>fgorski@chromium.org</owner> + <summary> + The number of milliseconds it takes for Feed content to be visible in the + UI. If content is not immediately available, this is conceptually the amount + of time a loading spinner is shown to the user. + </summary> +</histogram> + <histogram name="ContentSuggestions.Feed.RequestSizeKB.Compressed" units="KB"> <obsolete> Deprecated in favor of @@ -20595,7 +20618,7 @@ </summary> </histogram> -<histogram name="DemoMode.ActiveApp" enum="DemoModeApp" expires_after="M73"> +<histogram name="DemoMode.ActiveApp" enum="DemoModeApp" expires_after="M76"> <owner>michaelpg@chromium.org</owner> <owner>ovanieva@chromium.org</owner> <owner>tbarzic@chromium.org</owner> @@ -20606,7 +20629,7 @@ </histogram> <histogram name="DemoMode.IdleLogoutWarningEvent" - enum="DemoModeIdleLogoutWarningEvent" expires_after="M73"> + enum="DemoModeIdleLogoutWarningEvent" expires_after="M76"> <owner>michaelpg@chromium.org</owner> <owner>ovanieva@chromium.org</owner> <owner>wzang@chromium.org</owner> @@ -20619,7 +20642,7 @@ </histogram> <histogram name="DemoMode.ResourcesRemoval.Reason" - enum="DemoModeResourcesRemovalReason" expires_after="M73"> + enum="DemoModeResourcesRemovalReason" expires_after="M76"> <owner>michaelpg@chromium.org</owner> <owner>ovanieva@chromium.org</owner> <owner>tbarzic@chromium.org</owner> @@ -20632,7 +20655,7 @@ </histogram> <histogram name="DemoMode.ResourcesRemoval.Result" - enum="DemoModeResourcesRemovalResult" expires_after="M73"> + enum="DemoModeResourcesRemovalResult" expires_after="M76"> <owner>michaelpg@chromium.org</owner> <owner>ovanieva@chromium.org</owner> <owner>tbarzic@chromium.org</owner> @@ -20647,7 +20670,7 @@ </summary> </histogram> -<histogram name="DemoMode.SessionLength" units="minutes" expires_after="M73"> +<histogram name="DemoMode.SessionLength" units="minutes" expires_after="M76"> <owner>michaelpg@chromium.org</owner> <owner>ovanieva@chromium.org</owner> <owner>tbarzic@chromium.org</owner> @@ -46663,6 +46686,9 @@ <histogram name="Media.DXVAVDA.CreateDecoderStatus" enum="BooleanSuccess" expires_after="M73"> + <obsolete> + Removed 12/2018 since we had enough data to make a decision. + </obsolete> <owner>dalecurtis@chromium.org</owner> <owner>media-dev@chromium.org</owner> <summary> @@ -46682,6 +46708,9 @@ <histogram name="Media.DXVAVDA.GetDecoderConfigStatus" enum="BooleanSuccess" expires_after="M73"> + <obsolete> + Removed 12/2018 since we had enough data to make a decision. + </obsolete> <owner>dalecurtis@chromium.org</owner> <owner>media-dev@chromium.org</owner> <summary>
diff --git a/ui/accessibility/BUILD.gn b/ui/accessibility/BUILD.gn index 6f55117c..69a6c950 100644 --- a/ui/accessibility/BUILD.gn +++ b/ui/accessibility/BUILD.gn
@@ -95,6 +95,8 @@ "platform/ax_platform_node_test_helper.h", "platform/ax_unique_id.cc", "platform/ax_unique_id.h", + "platform/compute_attributes.cc", + "platform/compute_attributes.h", ] if (has_native_accessibility) {
diff --git a/ui/accessibility/platform/ax_platform_node_base.cc b/ui/accessibility/platform/ax_platform_node_base.cc index 8cba6b4..24f9d1e 100644 --- a/ui/accessibility/platform/ax_platform_node_base.cc +++ b/ui/accessibility/platform/ax_platform_node_base.cc
@@ -17,6 +17,7 @@ #include "ui/accessibility/ax_role_properties.h" #include "ui/accessibility/ax_tree_data.h" #include "ui/accessibility/platform/ax_platform_node_delegate.h" +#include "ui/accessibility/platform/compute_attributes.h" #include "ui/gfx/geometry/rect_conversions.h" namespace ui { @@ -914,9 +915,9 @@ const char* name, PlatformAttributeList* attributes) { DCHECK(attributes); - int value; - if (GetIntAttribute(attribute, &value)) { - std::string str_value = base::IntToString(value); + auto maybe_value = ComputeAttribute(delegate_, attribute); + if (maybe_value.has_value()) { + std::string str_value = base::IntToString(maybe_value.value()); AddAttributeToList(name, str_value, attributes); } }
diff --git a/ui/accessibility/platform/compute_attributes.cc b/ui/accessibility/platform/compute_attributes.cc new file mode 100644 index 0000000..3531a2e --- /dev/null +++ b/ui/accessibility/platform/compute_attributes.cc
@@ -0,0 +1,92 @@ +// 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/accessibility/platform/compute_attributes.h" + +#include <cstddef> + +#include "base/optional.h" +#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_node_data.h" +#include "ui/accessibility/platform/ax_platform_node_delegate.h" + +namespace ui { +namespace { + +base::Optional<int32_t> GetCellAttribute( + const ui::AXPlatformNodeDelegate* delegate, + ax::mojom::IntAttribute attribute) { + switch (attribute) { + case ax::mojom::IntAttribute::kAriaCellColumnIndex: + return delegate->GetTableCellAriaColIndex(); + case ax::mojom::IntAttribute::kAriaCellRowIndex: + return delegate->GetTableCellAriaRowIndex(); + case ax::mojom::IntAttribute::kTableCellColumnIndex: + return delegate->GetTableCellColIndex(); + case ax::mojom::IntAttribute::kTableCellRowIndex: + return delegate->GetTableCellRowIndex(); + case ax::mojom::IntAttribute::kTableCellColumnSpan: + return delegate->GetTableCellColSpan(); + case ax::mojom::IntAttribute::kTableCellRowSpan: + return delegate->GetTableCellRowSpan(); + default: + return base::nullopt; + } +} + +base::Optional<int32_t> GetRowAttribute( + const ui::AXPlatformNodeDelegate* delegate, + ax::mojom::IntAttribute attribute) { + if (attribute == ax::mojom::IntAttribute::kTableRowIndex) { + return delegate->GetTableRowRowIndex(); + } + return base::nullopt; +} + +base::Optional<int32_t> GetTableAttribute( + const ui::AXPlatformNodeDelegate* delegate, + ax::mojom::IntAttribute attribute) { + switch (attribute) { + case ax::mojom::IntAttribute::kTableColumnCount: + return delegate->GetTableColCount(); + case ax::mojom::IntAttribute::kTableRowCount: + return delegate->GetTableRowCount(); + case ax::mojom::IntAttribute::kAriaColumnCount: + return delegate->GetTableAriaColCount(); + case ax::mojom::IntAttribute::kAriaRowCount: + return delegate->GetTableAriaRowCount(); + default: + return base::nullopt; + } +} + +base::Optional<int32_t> GetFromData(const ui::AXPlatformNodeDelegate* delegate, + ax::mojom::IntAttribute attribute) { + int32_t value; + if (delegate->GetData().GetIntAttribute(attribute, &value)) { + return value; + } + return base::nullopt; +} + +} // namespace + +base::Optional<int32_t> ComputeAttribute( + const ui::AXPlatformNodeDelegate* delegate, + ax::mojom::IntAttribute attribute) { + base::Optional<int32_t> maybe_value = base::nullopt; + if (delegate->IsTableCellOrHeader()) + maybe_value = GetCellAttribute(delegate, attribute); + else if (delegate->IsTableRow()) + maybe_value = GetRowAttribute(delegate, attribute); + else if (delegate->IsTable()) + maybe_value = GetTableAttribute(delegate, attribute); + + if (!maybe_value.has_value()) { + return GetFromData(delegate, attribute); + } + return maybe_value; +} + +} // namespace ui
diff --git a/ui/accessibility/platform/compute_attributes.h b/ui/accessibility/platform/compute_attributes.h new file mode 100644 index 0000000..3a0eb470 --- /dev/null +++ b/ui/accessibility/platform/compute_attributes.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 UI_ACCESSIBILITY_PLATFORM_COMPUTE_ATTRIBUTES_H_ +#define UI_ACCESSIBILITY_PLATFORM_COMPUTE_ATTRIBUTES_H_ + +#include <cstddef> + +#include "base/optional.h" +#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_export.h" +#include "ui/accessibility/platform/ax_platform_node_delegate.h" + +namespace ui { + +// Compute the attribute value instead of returning the "raw" attribute value +// for those attributes that have computation methods. +AX_EXPORT base::Optional<int32_t> ComputeAttribute( + const ui::AXPlatformNodeDelegate* delegate, + ax::mojom::IntAttribute attribute); + +} // namespace ui + +#endif // UI_ACCESSIBILITY_PLATFORM_COMPUTE_ATTRIBUTES_H_
diff --git a/ui/aura/mus/input_method_mus.cc b/ui/aura/mus/input_method_mus.cc index 9a1d3c1..d68b1d70 100644 --- a/ui/aura/mus/input_method_mus.cc +++ b/ui/aura/mus/input_method_mus.cc
@@ -102,8 +102,15 @@ UpdateTextInputType(); - if (input_method_) - input_method_->OnTextInputTypeChanged(client->GetTextInputType()); + if (!input_method_) + return; + + auto text_input_state = ws::mojom::TextInputState::New(); + text_input_state->text_input_type = client->GetTextInputType(); + text_input_state->text_input_mode = client->GetTextInputMode(); + text_input_state->text_direction = client->GetTextDirection(); + text_input_state->text_input_flags = client->GetTextInputFlags(); + input_method_->OnTextInputStateChanged(std::move(text_input_state)); } void InputMethodMus::OnCaretBoundsChanged(const ui::TextInputClient* client) { @@ -194,10 +201,11 @@ text_input_client_->CreateInterfacePtrAndBind().PassInterface(); details->input_method_request = MakeRequest(&input_method_ptr_); input_method_ = input_method_ptr_.get(); - details->text_input_type = focused->GetTextInputType(); - details->text_input_mode = focused->GetTextInputMode(); - details->text_direction = focused->GetTextDirection(); - details->text_input_flags = focused->GetTextInputFlags(); + details->state = ws::mojom::TextInputState::New(); + details->state->text_input_type = focused->GetTextInputType(); + details->state->text_input_mode = focused->GetTextInputMode(); + details->state->text_direction = focused->GetTextDirection(); + details->state->text_input_flags = focused->GetTextInputFlags(); details->caret_bounds = focused->GetCaretBounds(); ime_driver_->StartSession(std::move(details)); }
diff --git a/ui/aura/mus/input_method_mus_unittest.cc b/ui/aura/mus/input_method_mus_unittest.cc index b70f263..7657e3d 100644 --- a/ui/aura/mus/input_method_mus_unittest.cc +++ b/ui/aura/mus/input_method_mus_unittest.cc
@@ -56,8 +56,9 @@ } // ui::ime::InputMethod: - void OnTextInputTypeChanged(ui::TextInputType text_input_type) override { - was_on_text_input_type_changed_called_ = true; + void OnTextInputStateChanged( + ws::mojom::TextInputStatePtr text_input_state) override { + was_on_text_input_state_changed_called_ = true; } void OnCaretBoundsChanged(const gfx::Rect& caret_bounds) override { was_on_caret_bounds_changed_called_ = true; @@ -71,8 +72,8 @@ was_show_virtual_keyboard_if_enabled_called_ = true; } - bool was_on_text_input_type_changed_called() { - return was_on_text_input_type_changed_called_; + bool was_on_text_input_state_changed_called() { + return was_on_text_input_state_changed_called_; } bool was_on_caret_bounds_changed_called() { @@ -88,7 +89,7 @@ } private: - bool was_on_text_input_type_changed_called_ = false; + bool was_on_text_input_state_changed_called_ = false; bool was_on_caret_bounds_changed_called_ = false; bool was_cancel_composition_called_ = false; bool was_show_virtual_keyboard_if_enabled_called_ = false; @@ -294,7 +295,7 @@ InputMethodMusTestApi::CallOnTextInputTypeChanged(&input_method_mus, &unfocused_input_client); - EXPECT_FALSE(test_input_method.was_on_text_input_type_changed_called()); + EXPECT_FALSE(test_input_method.was_on_text_input_state_changed_called()); } // Calling OnCaretBoundsChanged from unfocused client should
diff --git a/ui/aura/mus/window_tree_client.cc b/ui/aura/mus/window_tree_client.cc index a0dbdb0b..61c5144 100644 --- a/ui/aura/mus/window_tree_client.cc +++ b/ui/aura/mus/window_tree_client.cc
@@ -1500,15 +1500,17 @@ screen_provider_observer_binding_.Bind(std::move(observer)); } -void WindowTreeClient::OnOcclusionStateChanged( - ws::Id window_id, - ws::mojom::OcclusionState occlusion_state) { - WindowMus* window = GetWindowByServerId(window_id); - if (!window) - return; +void WindowTreeClient::OnOcclusionStatesChanged( + const base::flat_map<ws::Id, ws::mojom::OcclusionState>& + occlusion_changes) { + for (const auto& change : occlusion_changes) { + WindowMus* window = GetWindowByServerId(change.first); + if (!window) + continue; - WindowPortMus::Get(window->GetWindow()) - ->SetOcclusionStateFromServer(occlusion_state); + WindowPortMus::Get(window->GetWindow()) + ->SetOcclusionStateFromServer(change.second); + } } void WindowTreeClient::OnDisplaysChanged(
diff --git a/ui/aura/mus/window_tree_client.h b/ui/aura/mus/window_tree_client.h index 186f8e5c..b8fc484 100644 --- a/ui/aura/mus/window_tree_client.h +++ b/ui/aura/mus/window_tree_client.h
@@ -459,9 +459,9 @@ void RequestClose(ws::Id window_id) override; void GetScreenProviderObserver( ws::mojom::ScreenProviderObserverAssociatedRequest observer) override; - void OnOcclusionStateChanged( - ws::Id window_id, - ws::mojom::OcclusionState occlusion_state) override; + void OnOcclusionStatesChanged( + const base::flat_map<ws::Id, ws::mojom::OcclusionState>& + occlusion_changes) override; // ws::mojom::ScreenProviderObserver: void OnDisplaysChanged(std::vector<ws::mojom::WsDisplayPtr> ws_displays,
diff --git a/ui/aura/mus/window_tree_client_unittest.cc b/ui/aura/mus/window_tree_client_unittest.cc index 88ba2d1e..43116d0 100644 --- a/ui/aura/mus/window_tree_client_unittest.cc +++ b/ui/aura/mus/window_tree_client_unittest.cc
@@ -2666,8 +2666,8 @@ window.Hide(); } - window_tree_client()->OnOcclusionStateChanged( - server_id(&window), test.changed_state_from_server); + window_tree_client()->OnOcclusionStatesChanged( + {{server_id(&window), test.changed_state_from_server}}); EXPECT_EQ(test.expected_state, window.occlusion_state()) << test.name; } }
diff --git a/ui/chromeos/search_box/search_box_view_base.cc b/ui/chromeos/search_box/search_box_view_base.cc index 852b1231..d38aaa1c 100644 --- a/ui/chromeos/search_box/search_box_view_base.cc +++ b/ui/chromeos/search_box/search_box_view_base.cc
@@ -197,12 +197,12 @@ } void OnFocus() override { - search_box_view_->OnOnSearchBoxFocusedChanged(); + search_box_view_->OnSearchBoxFocusedChanged(); Textfield::OnFocus(); } void OnBlur() override { - search_box_view_->OnOnSearchBoxFocusedChanged(); + search_box_view_->OnSearchBoxFocusedChanged(); // Clear selection and set the caret to the end of the text. ClearSelection(); Textfield::OnBlur(); @@ -426,7 +426,7 @@ UpdateSearchBoxBorder(); } -void SearchBoxViewBase::OnOnSearchBoxFocusedChanged() { +void SearchBoxViewBase::OnSearchBoxFocusedChanged() { UpdateSearchBoxBorder(); Layout(); SchedulePaint();
diff --git a/ui/chromeos/search_box/search_box_view_base.h b/ui/chromeos/search_box/search_box_view_base.h index d8e0784..d01a1ae 100644 --- a/ui/chromeos/search_box/search_box_view_base.h +++ b/ui/chromeos/search_box/search_box_view_base.h
@@ -116,7 +116,7 @@ bool show_assistant_button() { return show_assistant_button_; } - void OnOnSearchBoxFocusedChanged(); + void OnSearchBoxFocusedChanged(); // Whether the trimmed query in the search box is empty. bool IsSearchBoxTrimmedQueryEmpty() const;
diff --git a/ui/compositor/host/host_context_factory_private.cc b/ui/compositor/host/host_context_factory_private.cc index e16c549..8e01fd6 100644 --- a/ui/compositor/host/host_context_factory_private.cc +++ b/ui/compositor/host/host_context_factory_private.cc
@@ -141,6 +141,14 @@ compositor_data_map_.erase(compositor); } +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; +} + std::unique_ptr<Reflector> HostContextFactoryPrivate::CreateReflector( Compositor* source, Layer* target) { @@ -258,14 +266,6 @@ 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;
diff --git a/ui/compositor/host/host_context_factory_private.h b/ui/compositor/host/host_context_factory_private.h index 69a441e9..a746302 100644 --- a/ui/compositor/host/host_context_factory_private.h +++ b/ui/compositor/host/host_context_factory_private.h
@@ -50,6 +50,19 @@ void UnconfigureCompositor(Compositor* compositor); + 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(); + // ContextFactoryPrivate implementation. std::unique_ptr<Reflector> CreateReflector(Compositor* source, Layer* target) override; @@ -72,20 +85,6 @@ 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();
diff --git a/ui/events/devices/input_device_observer_win.cc b/ui/events/devices/input_device_observer_win.cc index 0bb43a90..3508f0e 100644 --- a/ui/events/devices/input_device_observer_win.cc +++ b/ui/events/devices/input_device_observer_win.cc
@@ -12,12 +12,12 @@ #include <windows.h> // This macro provides the implementation for the observer notification methods. -#define NOTIFY_OBSERVERS(method_decl, input_device_types) \ - void InputDeviceObserverWin::method_decl { \ - for (InputDeviceEventObserver & observer : observers_) { \ - observer.OnInputDeviceConfigurationChanged( \ - InputDeviceEventObserver::input_device_types); \ - } \ +#define WIN_NOTIFY_OBSERVERS(method_decl, input_device_types) \ + void InputDeviceObserverWin::method_decl { \ + for (InputDeviceEventObserver & observer : observers_) { \ + observer.OnInputDeviceConfigurationChanged( \ + InputDeviceEventObserver::input_device_types); \ + } \ } namespace ui { @@ -27,7 +27,7 @@ // The registry subkey that contains information about the state of the // detachable/convertible laptop, it tells if the device has an accessible // keyboard. -// OEMs are expected to follow this guidelines to report docked/undocked state +// OEMs are expected to follow these guidelines to report docked/undocked state // https://msdn.microsoft.com/en-us/windows/hardware/commercialize/customize/desktop/unattend/microsoft-windows-gpiobuttons-convertibleslatemode const base::char16 kRegistryPriorityControl[] = L"System\\CurrentControlSet\\Control\\PriorityControl"; @@ -94,10 +94,10 @@ observers_.RemoveObserver(observer); } -NOTIFY_OBSERVERS(NotifyObserversKeyboardDeviceConfigurationChanged(), - kKeyboard); +WIN_NOTIFY_OBSERVERS(NotifyObserversKeyboardDeviceConfigurationChanged(), + kKeyboard); -NOTIFY_OBSERVERS(NotifyObserversTouchpadDeviceConfigurationChanged(), - kTouchpad); +WIN_NOTIFY_OBSERVERS(NotifyObserversTouchpadDeviceConfigurationChanged(), + kTouchpad); } // namespace ui
diff --git a/ui/file_manager/file_manager/foreground/js/metadata_box_controller.js b/ui/file_manager/file_manager/foreground/js/metadata_box_controller.js index 649a7ca1..732e673 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata_box_controller.js +++ b/ui/file_manager/file_manager/foreground/js/metadata_box_controller.js
@@ -230,8 +230,10 @@ this.isDirectorySizeLoading_ = true; chrome.fileManagerPrivate.getDirectorySize(entry, function(size) { this.isDirectorySizeLoading_ = false; - if (this.onDirectorySizeLoaded_) + if (this.onDirectorySizeLoaded_) { setTimeout(this.onDirectorySizeLoaded_.bind(null, entry)); + this.onDirectorySizeLoaded_ = null; + } if (this.quickViewModel_.getSelectedEntry() != entry) return;
diff --git a/ui/file_manager/file_manager/foreground/js/ui/banners.js b/ui/file_manager/file_manager/foreground/js/ui/banners.js index 1b9ce35..997cfeb 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/banners.js +++ b/ui/file_manager/file_manager/foreground/js/ui/banners.js
@@ -671,6 +671,10 @@ values[DOWNLOADS_WARNING_DISMISSED_KEY] = Date.now(); chrome.storage.local.set(values); box.hidden = true; + // We explicitly mark the banner-close element as hidden as due to the + // use of position absolute in it's layout it does not get hidden by + // hiding it's parent. + close.hidden = true; this.requestRelayout_(100); }.bind(this)); }
diff --git a/ui/gl/gl_image_native_pixmap.cc b/ui/gl/gl_image_native_pixmap.cc index 9ab046fa..712d8492 100644 --- a/ui/gl/gl_image_native_pixmap.cc +++ b/ui/gl/gl_image_native_pixmap.cc
@@ -328,15 +328,15 @@ } bool GLImageNativePixmap::CopyTexImage(unsigned target) { - if (egl_image_ == EGL_NO_IMAGE_KHR) { - // Pass-through image type fails to bind and copy; make sure we - // don't draw with uninitialized texture. - std::vector<unsigned char> data(size_.width() * size_.height() * 4); - glTexImage2D(target, 0, GL_RGBA, size_.width(), size_.height(), 0, GL_RGBA, - GL_UNSIGNED_BYTE, data.data()); - return true; - } - return false; + if (egl_image_ != EGL_NO_IMAGE_KHR) + return false; + + // Pass-through image type fails to bind and copy; make sure we + // don't draw with uninitialized texture. + std::vector<unsigned char> data(size_.width() * size_.height() * 4); + glTexImage2D(target, 0, GL_RGBA, size_.width(), size_.height(), 0, GL_RGBA, + GL_UNSIGNED_BYTE, data.data()); + return true; } bool GLImageNativePixmap::CopyTexSubImage(unsigned target,
diff --git a/ui/gl/gl_image_shared_memory.cc b/ui/gl/gl_image_shared_memory.cc index d736cd2..8ffb854 100644 --- a/ui/gl/gl_image_shared_memory.cc +++ b/ui/gl/gl_image_shared_memory.cc
@@ -9,7 +9,6 @@ #include "base/process/process_handle.h" #include "base/system/sys_info.h" #include "base/trace_event/memory_allocator_dump.h" -#include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/process_memory_dump.h" #include "ui/gfx/buffer_format_util.h" @@ -70,9 +69,7 @@ base::trace_event::ProcessMemoryDump* pmd, uint64_t process_tracing_id, const std::string& dump_name) { - size_t size_in_bytes = 0; - - size_in_bytes = stride() * GetSize().height(); + const size_t size_in_bytes = stride() * GetSize().height(); // Dump under "/shared_memory", as the base class may also dump to // "/texture_memory".
diff --git a/ui/strings/translations/ui_strings_sr.xtb b/ui/strings/translations/ui_strings_sr.xtb index 219a99c8..e959785 100644 --- a/ui/strings/translations/ui_strings_sr.xtb +++ b/ui/strings/translations/ui_strings_sr.xtb
@@ -125,7 +125,7 @@ <translation id="6483402905448010557">{SECONDS,plural, =1{Пре 1 секунду}one{Пре # секунду}few{Пре # секунде}other{Пре # секунди}}</translation> <translation id="654149438358937226">Блокирај сва обавештења</translation> <translation id="6567071839949112727">кликните на претходни елемент</translation> -<translation id="6578407462441924264">Неименовано</translation> +<translation id="6578407462441924264">Без имена</translation> <translation id="6612467943526193239">Да бисте изашли из калибрације, притисните Esc.</translation> <translation id="6620110761915583480">Чување датотеке</translation> <translation id="6699343763173986273">Следећа песма медија</translation>
diff --git a/ui/strings/ui_strings.grd b/ui/strings/ui_strings.grd index b262891..6681177 100644 --- a/ui/strings/ui_strings.grd +++ b/ui/strings/ui_strings.grd
@@ -857,6 +857,11 @@ <message name="IDS_CROSTINI_NOT_NOW_BUTTON" desc="Label for the button in the Crostini app restart dialog to dismiss the dialog."> Not now </message> + + <!-- Badging --> + <message name="IDS_SATURATED_BADGE_CONTENT" desc="The content to display when the application's badge is too large to display to indicate that the badge is more than a given maximum. This string should be as short as possible, preferably only one character beyond the content"> + <ph name="MAXIMUM_VALUE">$1<ex>99</ex></ph>+ + </message> </messages> </release> </grit>
diff --git a/ui/views/bubble/bubble_dialog_delegate_view.cc b/ui/views/bubble/bubble_dialog_delegate_view.cc index 47fcdff..558c5b65 100644 --- a/ui/views/bubble/bubble_dialog_delegate_view.cc +++ b/ui/views/bubble/bubble_dialog_delegate_view.cc
@@ -446,7 +446,7 @@ void BubbleDialogDelegateView::UpdateHighlightedButton(bool highlighted) { Button* button = Button::AsButton(highlighted_button_tracker_.view()); button = button ? button : Button::AsButton(anchor_view_tracker_->view()); - if (button) + if (button && highlight_button_when_shown_) button->SetHighlighted(highlighted); }
diff --git a/ui/views/bubble/bubble_dialog_delegate_view.h b/ui/views/bubble/bubble_dialog_delegate_view.h index a5b2d11c..2235c34f 100644 --- a/ui/views/bubble/bubble_dialog_delegate_view.h +++ b/ui/views/bubble/bubble_dialog_delegate_view.h
@@ -104,6 +104,10 @@ bool adjust_if_offscreen() const { return adjust_if_offscreen_; } void set_adjust_if_offscreen(bool adjust) { adjust_if_offscreen_ = adjust; } + void set_highlight_button_when_shown(bool highlight) { + highlight_button_when_shown_ = highlight; + } + // Get the arrow's anchor rect in screen space. virtual gfx::Rect GetAnchorRect() const; @@ -192,6 +196,10 @@ std::unique_ptr<ViewTracker> anchor_view_tracker_; Widget* anchor_widget_; + // Whether the |anchor_widget_| (or the |highlighted_button_tracker_|, when + // provided) should be highlighted when this bubble is shown. + bool highlight_button_when_shown_ = true; + // If provided, this button should be highlighted while the bubble is visible. // If not provided, the anchor_view will attempt to be highlighted. A // ViewTracker is used because the view can be deleted.
diff --git a/ui/views/layout/flex_layout.cc b/ui/views/layout/flex_layout.cc index 6208532..970bf09d 100644 --- a/ui/views/layout/flex_layout.cc +++ b/ui/views/layout/flex_layout.cc
@@ -430,7 +430,8 @@ for (const ChildLayout& child_layout : layout.child_layouts) { if (child_layout.excluded) continue; - layout_.SetViewVisibility(child_layout.view, child_layout.visible); + if (child_layout.visible != child_layout.view->visible()) + layout_.SetViewVisibility(child_layout.view, child_layout.visible); if (child_layout.visible) { NormalizedRect actual = child_layout.actual_bounds; actual.Offset(start.main(), start.cross()); @@ -975,8 +976,12 @@ // Add all the existing children when the layout manager is installed. // If new children are added, ViewAdded() will be called and we'll add data // there. - for (int i = 0; i < host->child_count(); ++i) - child_params_.emplace(host->child_at(i), internal::ChildLayoutParams()); + for (int i = 0; i < host->child_count(); ++i) { + View* const child = host->child_at(i); + internal::ChildLayoutParams child_layout_params; + child_layout_params.hidden_by_owner = !child->visible(); + child_params_.emplace(child, child_layout_params); + } } void FlexLayout::ViewAdded(View* host, View* view) {
diff --git a/ui/views/layout/flex_layout_unittest.cc b/ui/views/layout/flex_layout_unittest.cc index e9c456f..a33750b 100644 --- a/ui/views/layout/flex_layout_unittest.cc +++ b/ui/views/layout/flex_layout_unittest.cc
@@ -36,8 +36,18 @@ return minimum_size_.value_or(GetPreferredSize()); } + void SetVisible(bool visible) override { + View::SetVisible(visible); + ++set_visible_count_; + } + + int GetSetVisibleCount() const { return set_visible_count_; } + + void ResetCounts() { set_visible_count_ = 0; } + private: Optional<Size> minimum_size_; + int set_visible_count_ = 0; }; // Custom flex rule that snaps a view between its preffered size and half that @@ -72,16 +82,17 @@ layout_ = host_->SetLayoutManager(std::make_unique<FlexLayout>()); } - View* AddChild(const Size& preferred_size, - const Optional<Size>& minimum_size = Optional<Size>(), - bool visible = true) { + MockView* AddChild(const Size& preferred_size, + const Optional<Size>& minimum_size = Optional<Size>(), + bool visible = true) { return AddChild(host_.get(), preferred_size, minimum_size, visible); } - static View* AddChild(View* parent, - const Size& preferred_size, - const Optional<Size>& minimum_size = Optional<Size>(), - bool visible = true) { + static MockView* AddChild( + View* parent, + const Size& preferred_size, + const Optional<Size>& minimum_size = Optional<Size>(), + bool visible = true) { MockView* const child = new MockView(); child->SetPreferredSize(preferred_size); if (minimum_size.has_value()) @@ -230,6 +241,171 @@ EXPECT_EQ(Size(14, 11), host_->GetMinimumSize()); } +// Visibility and Inclusion Tests ---------------------------------------------- + +TEST_F(FlexLayoutTest, Layout_VisibilitySetBeforeInstall) { + // Since our test fixture creates a host and adds the layout manager right + // away, we need to create our own for this test. + std::unique_ptr<views::View> host = std::make_unique<views::View>(); + View* child1 = + AddChild(host.get(), Size(10, 10), base::Optional<Size>(), false); + View* child2 = + AddChild(host.get(), Size(10, 10), base::Optional<Size>(), true); + host->SetLayoutManager(std::make_unique<FlexLayout>()); + + host->Layout(); + EXPECT_FALSE(child1->visible()); + EXPECT_TRUE(child2->visible()); + + child1->SetVisible(true); + child2->SetVisible(false); + + host->Layout(); + EXPECT_TRUE(child1->visible()); + EXPECT_FALSE(child2->visible()); +} + +TEST_F(FlexLayoutTest, Layout_VisibilitySetAfterInstall) { + // Unlike the last test, we'll use the built-in host and layout manager since + // they're already set up. + View* child1 = AddChild(Size(10, 10), base::Optional<Size>(), false); + View* child2 = AddChild(Size(10, 10), base::Optional<Size>(), true); + + host_->Layout(); + EXPECT_FALSE(child1->visible()); + EXPECT_TRUE(child2->visible()); + + child1->SetVisible(true); + child2->SetVisible(false); + + host_->Layout(); + EXPECT_TRUE(child1->visible()); + EXPECT_FALSE(child2->visible()); +} + +TEST_F(FlexLayoutTest, Layout_VisibilitySetBeforeAdd) { + layout_->SetOrientation(LayoutOrientation::kHorizontal); + layout_->SetCollapseMargins(true); + layout_->SetInteriorMargin(Insets(5, 6, 7, 9)); + layout_->SetCrossAxisAlignment(LayoutAlignment::kStart); + View* child1 = AddChild(Size(12, 10)); + View* child2 = AddChild(Size(13, 11), Optional<Size>(), false); + View* child3 = AddChild(Size(17, 13)); + + host_->Layout(); + EXPECT_EQ(true, layout_->IsHiddenByOwner(child2)); + EXPECT_FALSE(child2->visible()); + EXPECT_EQ(Rect(6, 5, 12, 10), child1->bounds()); + EXPECT_EQ(Rect(18, 5, 17, 13), child3->bounds()); + EXPECT_EQ(Size(44, 25), host_->GetPreferredSize()); + + // This should have no additional effect since the child is already invisible. + child2->SetVisible(false); + host_->Layout(); + EXPECT_EQ(true, layout_->IsHiddenByOwner(child2)); + EXPECT_FALSE(child2->visible()); + EXPECT_EQ(Rect(6, 5, 12, 10), child1->bounds()); + EXPECT_EQ(Rect(18, 5, 17, 13), child3->bounds()); + EXPECT_EQ(Size(44, 25), host_->GetPreferredSize()); + + child2->SetVisible(true); + host_->Layout(); + std::vector<Rect> expected{Rect(6, 5, 12, 10), Rect(18, 5, 13, 11), + Rect(31, 5, 17, 13)}; + EXPECT_EQ(false, layout_->IsHiddenByOwner(child2)); + EXPECT_TRUE(child2->visible()); + EXPECT_EQ(expected, GetChildBounds()); + EXPECT_EQ(Size(57, 25), host_->GetPreferredSize()); +} + +TEST_F(FlexLayoutTest, Layout_VisibilitySetAfterAdd) { + layout_->SetOrientation(LayoutOrientation::kHorizontal); + layout_->SetCollapseMargins(true); + layout_->SetInteriorMargin(Insets(5, 6, 7, 9)); + layout_->SetCrossAxisAlignment(LayoutAlignment::kStart); + View* child1 = AddChild(Size(12, 10)); + View* child2 = AddChild(Size(13, 11)); + View* child3 = AddChild(Size(17, 13)); + + child2->SetVisible(false); + host_->Layout(); + EXPECT_EQ(true, layout_->IsHiddenByOwner(child2)); + EXPECT_FALSE(child2->visible()); + EXPECT_EQ(Rect(6, 5, 12, 10), child1->bounds()); + EXPECT_EQ(Rect(18, 5, 17, 13), child3->bounds()); + EXPECT_EQ(Size(44, 25), host_->GetPreferredSize()); + + child2->SetVisible(true); + host_->Layout(); + std::vector<Rect> expected{Rect(6, 5, 12, 10), Rect(18, 5, 13, 11), + Rect(31, 5, 17, 13)}; + EXPECT_EQ(false, layout_->IsHiddenByOwner(child2)); + EXPECT_TRUE(child2->visible()); + EXPECT_EQ(expected, GetChildBounds()); + EXPECT_EQ(Size(57, 25), host_->GetPreferredSize()); +} + +TEST_F(FlexLayoutTest, + Layout_ViewVisibilitySetNotContingentOnActualVisibility) { + layout_->SetOrientation(LayoutOrientation::kHorizontal); + layout_->SetCollapseMargins(true); + layout_->SetInteriorMargin(Insets(5, 6, 7, 9)); + layout_->SetCrossAxisAlignment(LayoutAlignment::kStart); + View* child1 = AddChild(Size(12, 10)); + View* child2 = AddChild(Size(13, 11)); + View* child3 = AddChild(Size(17, 13)); + layout_->SetFlexForView(child2, kDropOut); + + // Layout makes child view invisible due to flex rule. + host_->SetSize(Size(40, 25)); + host_->Layout(); + EXPECT_EQ(false, layout_->IsHiddenByOwner(child2)); + EXPECT_FALSE(child2->visible()); + EXPECT_EQ(Rect(6, 5, 12, 10), child1->bounds()); + EXPECT_EQ(Rect(18, 5, 17, 13), child3->bounds()); + // Preferred size should still reflect child hidden due to flex rule. + EXPECT_EQ(Size(57, 25), host_->GetPreferredSize()); + + // Now we will make child explicitly hidden. + child2->SetVisible(false); + EXPECT_EQ(true, layout_->IsHiddenByOwner(child2)); + + // Layout is the same, but we should report that the view is hidden by owner. + host_->Layout(); + EXPECT_EQ(true, layout_->IsHiddenByOwner(child2)); + EXPECT_FALSE(child2->visible()); + EXPECT_EQ(Rect(6, 5, 12, 10), child1->bounds()); + EXPECT_EQ(Rect(18, 5, 17, 13), child3->bounds()); + EXPECT_EQ(Size(44, 25), host_->GetPreferredSize()); +} + +TEST_F(FlexLayoutTest, Layout_Exlcude) { + layout_->SetOrientation(LayoutOrientation::kHorizontal); + layout_->SetCollapseMargins(true); + layout_->SetInteriorMargin(Insets(5, 6, 7, 9)); + layout_->SetCrossAxisAlignment(LayoutAlignment::kStart); + const View* child1 = AddChild(Size(12, 10)); + View* child2 = AddChild(Size(13, 11)); + const View* child3 = AddChild(Size(17, 13)); + + layout_->SetViewExcluded(child2, true); + child2->SetBounds(3, 3, 3, 3); + host_->Layout(); + EXPECT_EQ(true, layout_->IsViewExcluded(child2)); + EXPECT_EQ(Rect(3, 3, 3, 3), child2->bounds()); + EXPECT_EQ(Rect(6, 5, 12, 10), child1->bounds()); + EXPECT_EQ(Rect(18, 5, 17, 13), child3->bounds()); + EXPECT_EQ(Size(44, 25), host_->GetPreferredSize()); + + layout_->SetViewExcluded(child2, false); + host_->Layout(); + std::vector<Rect> expected{Rect(6, 5, 12, 10), Rect(18, 5, 13, 11), + Rect(31, 5, 17, 13)}; + EXPECT_EQ(false, layout_->IsViewExcluded(child2)); + EXPECT_EQ(expected, GetChildBounds()); + EXPECT_EQ(Size(57, 25), host_->GetPreferredSize()); +} + // Child Positioning Tests ----------------------------------------------------- TEST_F(FlexLayoutTest, LayoutSingleView_Horizontal) { @@ -372,129 +548,6 @@ EXPECT_EQ(Size(32, 46), host_->GetPreferredSize()); } -TEST_F(FlexLayoutTest, LayoutMultipleViews_VisibilitySetBeforeAdd) { - layout_->SetOrientation(LayoutOrientation::kHorizontal); - layout_->SetCollapseMargins(true); - layout_->SetInteriorMargin(Insets(5, 6, 7, 9)); - layout_->SetCrossAxisAlignment(LayoutAlignment::kStart); - View* child1 = AddChild(Size(12, 10)); - View* child2 = AddChild(Size(13, 11), Optional<Size>(), false); - View* child3 = AddChild(Size(17, 13)); - - host_->Layout(); - EXPECT_EQ(true, layout_->IsHiddenByOwner(child2)); - EXPECT_FALSE(child2->visible()); - EXPECT_EQ(Rect(6, 5, 12, 10), child1->bounds()); - EXPECT_EQ(Rect(18, 5, 17, 13), child3->bounds()); - EXPECT_EQ(Size(44, 25), host_->GetPreferredSize()); - - // This should have no additional effect since the child is already invisible. - child2->SetVisible(false); - host_->Layout(); - EXPECT_EQ(true, layout_->IsHiddenByOwner(child2)); - EXPECT_FALSE(child2->visible()); - EXPECT_EQ(Rect(6, 5, 12, 10), child1->bounds()); - EXPECT_EQ(Rect(18, 5, 17, 13), child3->bounds()); - EXPECT_EQ(Size(44, 25), host_->GetPreferredSize()); - - child2->SetVisible(true); - host_->Layout(); - std::vector<Rect> expected{Rect(6, 5, 12, 10), Rect(18, 5, 13, 11), - Rect(31, 5, 17, 13)}; - EXPECT_EQ(false, layout_->IsHiddenByOwner(child2)); - EXPECT_TRUE(child2->visible()); - EXPECT_EQ(expected, GetChildBounds()); - EXPECT_EQ(Size(57, 25), host_->GetPreferredSize()); -} - -TEST_F(FlexLayoutTest, LayoutMultipleViews_VisibilitySetAfterAdd) { - layout_->SetOrientation(LayoutOrientation::kHorizontal); - layout_->SetCollapseMargins(true); - layout_->SetInteriorMargin(Insets(5, 6, 7, 9)); - layout_->SetCrossAxisAlignment(LayoutAlignment::kStart); - View* child1 = AddChild(Size(12, 10)); - View* child2 = AddChild(Size(13, 11)); - View* child3 = AddChild(Size(17, 13)); - - child2->SetVisible(false); - host_->Layout(); - EXPECT_EQ(true, layout_->IsHiddenByOwner(child2)); - EXPECT_FALSE(child2->visible()); - EXPECT_EQ(Rect(6, 5, 12, 10), child1->bounds()); - EXPECT_EQ(Rect(18, 5, 17, 13), child3->bounds()); - EXPECT_EQ(Size(44, 25), host_->GetPreferredSize()); - - child2->SetVisible(true); - host_->Layout(); - std::vector<Rect> expected{Rect(6, 5, 12, 10), Rect(18, 5, 13, 11), - Rect(31, 5, 17, 13)}; - EXPECT_EQ(false, layout_->IsHiddenByOwner(child2)); - EXPECT_TRUE(child2->visible()); - EXPECT_EQ(expected, GetChildBounds()); - EXPECT_EQ(Size(57, 25), host_->GetPreferredSize()); -} - -TEST_F(FlexLayoutTest, - LayoutMultipleViews_ViewVisibilitySetNotContingentOnActualVisibility) { - layout_->SetOrientation(LayoutOrientation::kHorizontal); - layout_->SetCollapseMargins(true); - layout_->SetInteriorMargin(Insets(5, 6, 7, 9)); - layout_->SetCrossAxisAlignment(LayoutAlignment::kStart); - View* child1 = AddChild(Size(12, 10)); - View* child2 = AddChild(Size(13, 11)); - View* child3 = AddChild(Size(17, 13)); - layout_->SetFlexForView(child2, kDropOut); - - // Layout makes child view invisible due to flex rule. - host_->SetSize(Size(40, 25)); - host_->Layout(); - EXPECT_EQ(false, layout_->IsHiddenByOwner(child2)); - EXPECT_FALSE(child2->visible()); - EXPECT_EQ(Rect(6, 5, 12, 10), child1->bounds()); - EXPECT_EQ(Rect(18, 5, 17, 13), child3->bounds()); - // Preferred size should still reflect child hidden due to flex rule. - EXPECT_EQ(Size(57, 25), host_->GetPreferredSize()); - - // Now we will make child explicitly hidden. - child2->SetVisible(false); - EXPECT_EQ(true, layout_->IsHiddenByOwner(child2)); - - // Layout is the same, but we should report that the view is hidden by owner. - host_->Layout(); - EXPECT_EQ(true, layout_->IsHiddenByOwner(child2)); - EXPECT_FALSE(child2->visible()); - EXPECT_EQ(Rect(6, 5, 12, 10), child1->bounds()); - EXPECT_EQ(Rect(18, 5, 17, 13), child3->bounds()); - EXPECT_EQ(Size(44, 25), host_->GetPreferredSize()); -} - -TEST_F(FlexLayoutTest, LayoutMultipleViews_Exlcude) { - layout_->SetOrientation(LayoutOrientation::kHorizontal); - layout_->SetCollapseMargins(true); - layout_->SetInteriorMargin(Insets(5, 6, 7, 9)); - layout_->SetCrossAxisAlignment(LayoutAlignment::kStart); - const View* child1 = AddChild(Size(12, 10)); - View* child2 = AddChild(Size(13, 11)); - const View* child3 = AddChild(Size(17, 13)); - - layout_->SetViewExcluded(child2, true); - child2->SetBounds(3, 3, 3, 3); - host_->Layout(); - EXPECT_EQ(true, layout_->IsViewExcluded(child2)); - EXPECT_EQ(Rect(3, 3, 3, 3), child2->bounds()); - EXPECT_EQ(Rect(6, 5, 12, 10), child1->bounds()); - EXPECT_EQ(Rect(18, 5, 17, 13), child3->bounds()); - EXPECT_EQ(Size(44, 25), host_->GetPreferredSize()); - - layout_->SetViewExcluded(child2, false); - host_->Layout(); - std::vector<Rect> expected{Rect(6, 5, 12, 10), Rect(18, 5, 13, 11), - Rect(31, 5, 17, 13)}; - EXPECT_EQ(false, layout_->IsViewExcluded(child2)); - EXPECT_EQ(expected, GetChildBounds()); - EXPECT_EQ(Size(57, 25), host_->GetPreferredSize()); -} - TEST_F(FlexLayoutTest, LayoutMultipleViews_MarginAndSpacing_NoCollapse_Horizontal) { layout_->SetOrientation(LayoutOrientation::kHorizontal); @@ -1464,6 +1517,54 @@ EXPECT_FALSE(child->visible()); } +TEST_F(FlexLayoutTest, Layout_OnlyCallsSetViewVisibilityWhenNecessary) { + layout_->SetOrientation(LayoutOrientation::kHorizontal); + layout_->SetCollapseMargins(true); + layout_->SetInteriorMargin(Insets(5)); + layout_->SetMainAxisAlignment(LayoutAlignment::kStart); + layout_->SetCrossAxisAlignment(LayoutAlignment::kStart); + layout_->SetDefaultChildMargins(gfx::Insets(5)); + MockView* child1 = AddChild(Size(20, 10), Size(5, 5)); + MockView* child2 = AddChild(Size(20, 10), Size(5, 5)); + layout_->SetFlexForView(child1, kFlex1ScaleToZero); + layout_->SetFlexForView(child2, kFlex1ScaleToMinimumHighPriority); + + child1->ResetCounts(); + child2->ResetCounts(); + host_->SetSize(Size(40, 20)); + host_->Layout(); + EXPECT_TRUE(child1->visible()); + EXPECT_TRUE(child2->visible()); + EXPECT_EQ(0, child1->GetSetVisibleCount()); + EXPECT_EQ(0, child2->GetSetVisibleCount()); + + host_->SetSize(Size(35, 20)); + host_->Layout(); + EXPECT_FALSE(child1->visible()); + EXPECT_TRUE(child2->visible()); + EXPECT_EQ(1, child1->GetSetVisibleCount()); + EXPECT_EQ(0, child2->GetSetVisibleCount()); + + child1->ResetCounts(); + child2->ResetCounts(); + host_->SetSize(Size(30, 20)); + host_->Layout(); + EXPECT_FALSE(child1->visible()); + EXPECT_TRUE(child2->visible()); + EXPECT_EQ(0, child1->GetSetVisibleCount()); + EXPECT_EQ(0, child2->GetSetVisibleCount()); + + child1->SetVisible(false); + child1->ResetCounts(); + + host_->SetSize(Size(40, 20)); + host_->Layout(); + EXPECT_FALSE(child1->visible()); + EXPECT_TRUE(child2->visible()); + EXPECT_EQ(0, child1->GetSetVisibleCount()); + EXPECT_EQ(0, child2->GetSetVisibleCount()); +} + // Nested Layout Tests --------------------------------------------------------- class NestedFlexLayoutTest : public FlexLayoutTest {
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc index 252001f8..2d145e6a 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -83,6 +83,7 @@ static aura::Window* CreateParentWindow(aura::Window* child_window, const gfx::Rect& bounds, bool full_screen, + bool is_menu, bool root_is_always_on_top) { // This instance will get deleted when the widget is destroyed. DesktopNativeWidgetTopLevelHandler* top_level_handler = @@ -91,8 +92,9 @@ child_window->SetBounds(gfx::Rect(bounds.size())); Widget::InitParams init_params; - init_params.type = full_screen ? Widget::InitParams::TYPE_WINDOW : - Widget::InitParams::TYPE_POPUP; + init_params.type = full_screen ? Widget::InitParams::TYPE_WINDOW + : is_menu ? Widget::InitParams::TYPE_MENU + : Widget::InitParams::TYPE_POPUP; init_params.bounds = bounds; init_params.ownership = Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET; init_params.layer_type = ui::LAYER_NOT_DRAWN; @@ -198,7 +200,7 @@ root_is_always_on_top = native_widget->IsAlwaysOnTop(); return DesktopNativeWidgetTopLevelHandler::CreateParentWindow( - window, bounds, is_fullscreen, root_is_always_on_top); + window, bounds, is_fullscreen, is_menu, root_is_always_on_top); } return root_window_; }
diff --git a/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js b/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js index 1d53aed..f5664dd 100644 --- a/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js +++ b/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js
@@ -250,6 +250,13 @@ if ('SharedSetting' in property) return property['SharedSetting']; + // Effective, UserEditable or DeviceEditable properties may not have a value + // set. + if ('Effective' in property || 'UserEditable' in property || + 'DeviceEditable' in property) { + return undefined; + } + console.error( 'getActiveValue called on invalid ONC object: ' + JSON.stringify(property)); @@ -276,7 +283,11 @@ * @return {boolean} */ CrOnc.isSimpleProperty = function(property) { - for (const prop of ['Active', 'Effective', 'UserSetting', 'SharedSetting']) { + const requiredProperties = [ + 'Active', 'Effective', 'UserSetting', 'SharedSetting', 'UserEditable', + 'DeviceEditable' + ]; + for (const prop of requiredProperties) { if (prop in property) return true; } @@ -298,21 +309,14 @@ for (let i = 0; i < keys.length; ++i) { const k = keys[i]; const property = properties[k]; - // Skip policy properties with no effective value. - // TODO(nikitapodguzov@ / raleksandrov@): Remove this when crbug.com/888959 - // providing dummy values for password fields will be fixed. - if ('Effective' in property && !(property.Effective in property)) - continue; let propertyValue; - if (CrOnc.isSimpleProperty(property)) - propertyValue = CrOnc.getActiveValue(property); - else - propertyValue = CrOnc.getActiveProperties(property); - if (propertyValue == undefined) { - console.error( - 'getActiveProperties called on invalid ONC object: ' + - JSON.stringify(properties)); - return undefined; + if (typeof property === 'object') { + if (CrOnc.isSimpleProperty(property)) + propertyValue = CrOnc.getActiveValue(property); + else + propertyValue = CrOnc.getActiveProperties(property); + } else { + propertyValue = property; } result[k] = propertyValue; }
diff --git a/ui/webui/resources/cr_elements/cr_slider/cr_slider.html b/ui/webui/resources/cr_elements/cr_slider/cr_slider.html index 9ba11dc..bf0fb808 100644 --- a/ui/webui/resources/cr_elements/cr_slider/cr_slider.html +++ b/ui/webui/resources/cr_elements/cr_slider/cr_slider.html
@@ -207,7 +207,8 @@ </div> </div> <div id="knobContainer"> - <div id="knob" on-transitionend="onKnobTransitionEnd_"></div> + <div id="knob" on-transitionend="onKnobTransitionEnd_" + on-keydown="onKnobKeydown_"></div> </div> <div id="labelContainer" aria-label="[[label_]]"> <div id="label">[[label_]]</div>
diff --git a/ui/webui/resources/cr_elements/cr_slider/cr_slider.js b/ui/webui/resources/cr_elements/cr_slider/cr_slider.js index 35214d1..1967263 100644 --- a/ui/webui/resources/cr_elements/cr_slider/cr_slider.js +++ b/ui/webui/resources/cr_elements/cr_slider/cr_slider.js
@@ -273,6 +273,10 @@ /** @private */ onFocus_: function() { this.holdDown_ = true; + + if (this.shadowRoot.activeElement == this.$.knob) + return; + this.$.knob.focus(); }, /** @private */ @@ -313,6 +317,21 @@ } }, + /** + * This code is taken from cr-input. See https://crbug.com/832177#c31 for + * the CL that handles escaping focus from the shadow DOM. + * TODO(aee): see if a common behavior can be extracted from cr-slider and + * cr-input with regards to focusing an element in the shadow DOM and + * also being a focusable component. It may be useful for other + * components. + * @param {!KeyboardEvent} e + * @private + */ + onKnobKeydown_: function(e) { + if (e.shiftKey && e.key === 'Tab') + this.focus(); + }, + /** @private */ onKnobTransitionEnd_: function() { this.transiting_ = false;
diff --git a/webrunner/BUILD.gn b/webrunner/BUILD.gn index 37f3061..a524f9f 100644 --- a/webrunner/BUILD.gn +++ b/webrunner/BUILD.gn
@@ -117,15 +117,17 @@ ] } -# TODO(crbug.com/901955): This target is to be used for both unit tests and -# integration tests. test("castrunner_tests") { sources = [ + "app/cast/cast_runner_integration_test.cc", "app/cast/cast_runner_unittest.cc", + "app/cast/test_common.cc", + "app/cast/test_common.h", ] deps = [ ":app_config_manager_test_support", ":castrunner_common", + ":test_common", ":test_support", "//base/test:run_all_unittests", "//base/test:test_support", @@ -218,6 +220,7 @@ sources = [ "test/fake_context.cc", "test/fake_context.h", + "test/promise.h", ] deps = [ "//base", @@ -429,6 +432,7 @@ ":named_message_port_connector", ":service_lib", ":test_common", + ":test_support", ":web_fidl", "//base/test:test_support", "//content/public/browser",
diff --git a/webrunner/app/cast/cast_runner.cc b/webrunner/app/cast/cast_runner.cc index 686c20c..660843f 100644 --- a/webrunner/app/cast/cast_runner.cc +++ b/webrunner/app/cast/cast_runner.cc
@@ -25,21 +25,6 @@ CastRunner::~CastRunner() = default; -void CastRunner::GetConfigCallback( - fuchsia::sys::StartupInfo startup_info, - fidl::InterfaceRequest<fuchsia::sys::ComponentController> - controller_request, - chromium::cast::ApplicationConfigPtr app_config) { - // If a config was returned then use it to launch a component. - if (!app_config) - return; - - GURL cast_app_url(*app_config->web_url); - RegisterComponent(webrunner::WebComponent::ForUrlRequest( - this, std::move(cast_app_url), std::move(startup_info), - std::move(controller_request))); -} - void CastRunner::StartComponent( fuchsia::sys::Package package, fuchsia::sys::StartupInfo startup_info, @@ -70,4 +55,25 @@ }); } +void CastRunner::GetConfigCallback( + fuchsia::sys::StartupInfo startup_info, + fidl::InterfaceRequest<fuchsia::sys::ComponentController> + controller_request, + chromium::cast::ApplicationConfigPtr app_config) { + if (!app_config) { + DLOG(WARNING) << "No ApplicationConfig was found."; + + // For test purposes, we need to call RegisterComponent even if there is no + // URL to launch. + RegisterComponent(std::unique_ptr<webrunner::WebComponent>(nullptr)); + return; + } + + // If a config was returned then use it to launch a component. + GURL cast_app_url(*app_config->web_url); + RegisterComponent(webrunner::WebComponent::ForUrlRequest( + this, std::move(cast_app_url), std::move(startup_info), + std::move(controller_request))); +} + } // namespace castrunner
diff --git a/webrunner/app/cast/cast_runner.h b/webrunner/app/cast/cast_runner.h index 59a363c..a90f710b00 100644 --- a/webrunner/app/cast/cast_runner.h +++ b/webrunner/app/cast/cast_runner.h
@@ -23,12 +23,6 @@ ~CastRunner() override; - void GetConfigCallback( - fuchsia::sys::StartupInfo startup_info, - fidl::InterfaceRequest<fuchsia::sys::ComponentController> - controller_request, - chromium::cast::ApplicationConfigPtr app_config); - // fuchsia::sys::Runner implementation. void StartComponent(fuchsia::sys::Package package, fuchsia::sys::StartupInfo startup_info, @@ -38,6 +32,12 @@ private: chromium::cast::ApplicationConfigManagerPtr app_config_manager_; + void GetConfigCallback( + fuchsia::sys::StartupInfo startup_info, + fidl::InterfaceRequest<fuchsia::sys::ComponentController> + controller_request, + chromium::cast::ApplicationConfigPtr app_config); + DISALLOW_COPY_AND_ASSIGN(CastRunner); };
diff --git a/webrunner/app/cast/cast_runner_integration_test.cc b/webrunner/app/cast/cast_runner_integration_test.cc new file mode 100644 index 0000000..c531286a --- /dev/null +++ b/webrunner/app/cast/cast_runner_integration_test.cc
@@ -0,0 +1,160 @@ +// 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 <lib/fidl/cpp/binding.h> +#include <lib/zx/channel.h> + +#include "base/fuchsia/component_context.h" +#include "base/fuchsia/fuchsia_logging.h" +#include "base/fuchsia/service_directory.h" +#include "base/message_loop/message_loop.h" +#include "base/strings/stringprintf.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "webrunner/app/cast/application_config_manager/test/fake_application_config_manager.h" +#include "webrunner/app/cast/cast_runner.h" +#include "webrunner/app/cast/test_common.h" +#include "webrunner/app/common/web_component.h" +#include "webrunner/app/common/web_content_runner.h" +#include "webrunner/common/test/run_with_timeout.h" +#include "webrunner/test/promise.h" + +namespace castrunner { + +namespace { + +void ComponentErrorHandler(zx_status_t status) { + ZX_LOG(ERROR, status) << "Component launch failed."; + ADD_FAILURE(); +} + +} // namespace + +class CastRunnerIntegrationTest : public testing::Test { + public: + CastRunnerIntegrationTest() { + // Create a new test ServiceDirectory, and a test ComponentContext + // connected to it, for the test to use to drive the CastRunner. + zx::channel service_directory_request, service_directory_client; + zx_status_t status = zx::channel::create(0, &service_directory_client, + &service_directory_request); + ZX_CHECK(status == ZX_OK, status) << "zx_channel_create"; + + test_service_directory_ = std::make_unique<base::fuchsia::ServiceDirectory>( + std::move(service_directory_request)); + test_component_context_ = std::make_unique<base::fuchsia::ComponentContext>( + std::move(service_directory_client)); + + // Create the AppConfigManager. + app_config_manager_ = + std::make_unique<castrunner::test::FakeApplicationConfigManager>( + &test_server_); + app_config_binding_ = std::make_unique< + fidl::Binding<chromium::cast::ApplicationConfigManager>>( + app_config_manager_.get()); + chromium::cast::ApplicationConfigManagerPtr app_config_manager_interface; + app_config_binding_->Bind(app_config_manager_interface.NewRequest()); + + // Create the CastRunner, published into |test_service_directory_|. + cast_runner_ = std::make_unique<CastRunner>( + test_service_directory_.get(), + webrunner::WebContentRunner::CreateDefaultWebContext(), + std::move(app_config_manager_interface), + cast_runner_run_loop_.QuitClosure()); + + // Connect to the CastRunner's fuchsia.sys.Runner interface. + cast_runner_ptr_ = + test_component_context_->ConnectToService<fuchsia::sys::Runner>(); + cast_runner_ptr_.set_error_handler([this](zx_status_t status) { + ZX_LOG(ERROR, status) << "CastRunner closed channel."; + ADD_FAILURE(); + cast_runner_run_loop_.Quit(); + }); + } + + void SetUp() override { ASSERT_TRUE(test_server_.Start()); } + + void TearDown() override { + // Disconnect the CastRunner. + cast_runner_ptr_.Unbind(); + cast_runner_run_loop_.Run(); + } + + protected: + base::MessageLoopForIO message_loop_; + + net::EmbeddedTestServer test_server_; + + std::unique_ptr<castrunner::test::FakeApplicationConfigManager> + app_config_manager_; + std::unique_ptr<fidl::Binding<chromium::cast::ApplicationConfigManager>> + app_config_binding_; + + // ServiceDirectory into which the CastRunner will publish itself. + std::unique_ptr<base::fuchsia::ServiceDirectory> test_service_directory_; + std::unique_ptr<base::fuchsia::ComponentContext> test_component_context_; + + std::unique_ptr<CastRunner> cast_runner_; + fuchsia::sys::RunnerPtr cast_runner_ptr_; + base::RunLoop cast_runner_run_loop_; + + DISALLOW_COPY_AND_ASSIGN(CastRunnerIntegrationTest); +}; + +// A basic integration test ensuring a basic cast request launches the right +// URL in the Chromium service. +TEST_F(CastRunnerIntegrationTest, BasicRequest) { + // Launch the test-app component. + fuchsia::sys::ComponentControllerPtr component_controller_ptr; + base::fuchsia::ComponentContext component_services(StartCastComponent( + base::StringPrintf( + "cast:%s", + castrunner::test::FakeApplicationConfigManager::kTestCastAppId), + &cast_runner_ptr_, component_controller_ptr.NewRequest())); + component_controller_ptr.set_error_handler(&ComponentErrorHandler); + + // Access the NavigationController from the WebComponent. The test will hang + // here if no WebComponent was created. + chromium::web::NavigationControllerPtr nav_controller; + { + base::RunLoop run_loop; + webrunner::Promise<webrunner::WebComponent*> web_component( + run_loop.QuitClosure()); + cast_runner_->GetWebComponentForTest(web_component.GetReceiveCallback()); + webrunner::CheckRunWithTimeout(&run_loop); + ASSERT_NE(*web_component, nullptr); + (*web_component) + ->frame() + ->GetNavigationController(nav_controller.NewRequest()); + } + + // Ensure the NavigationEntry has the expected URL. + { + base::RunLoop run_loop; + webrunner::Promise<std::unique_ptr<chromium::web::NavigationEntry>> + nav_entry(run_loop.QuitClosure()); + nav_controller->GetVisibleEntry( + webrunner::ConvertToFitFunction(nav_entry.GetReceiveCallback())); + webrunner::CheckRunWithTimeout(&run_loop); + EXPECT_EQ(nav_entry->get()->url, test_server_.base_url().spec()); + } +} + +TEST_F(CastRunnerIntegrationTest, IncorrectCastAppId) { + // Launch the test-app component. + fuchsia::sys::ComponentControllerPtr component_controller_ptr; + base::fuchsia::ComponentContext component_services( + StartCastComponent("cast:99999999", &cast_runner_ptr_, + component_controller_ptr.NewRequest())); + component_controller_ptr.set_error_handler(&ComponentErrorHandler); + + // Ensure no WebComponent was created. + base::RunLoop run_loop; + webrunner::Promise<webrunner::WebComponent*> web_component( + run_loop.QuitClosure()); + cast_runner_->GetWebComponentForTest(web_component.GetReceiveCallback()); + webrunner::CheckRunWithTimeout(&run_loop); + EXPECT_EQ(*web_component, nullptr); +} + +} // namespace castrunner
diff --git a/webrunner/app/cast/cast_runner_unittest.cc b/webrunner/app/cast/cast_runner_unittest.cc index f004e26f..eb69b1f 100644 --- a/webrunner/app/cast/cast_runner_unittest.cc +++ b/webrunner/app/cast/cast_runner_unittest.cc
@@ -12,17 +12,17 @@ #include "base/fuchsia/fuchsia_logging.h" #include "base/fuchsia/service_directory.h" #include "base/message_loop/message_loop.h" -#include "base/strings/string_piece.h" +#include "base/strings/stringprintf.h" #include "testing/gtest/include/gtest/gtest.h" #include "webrunner/app/cast/application_config_manager/test/fake_application_config_manager.h" -#include "webrunner/fidl/chromium/web/cpp/fidl.h" +#include "webrunner/app/cast/test_common.h" #include "webrunner/test/fake_context.h" namespace castrunner { -class CastRunnerTest : public testing::Test { +class CastRunnerUnitTest : public testing::Test { public: - CastRunnerTest() + CastRunnerUnitTest() : fake_context_binding_(&fake_context_, fake_context_ptr_.NewRequest()) { // Create a new ServiceDirectory, and a scoped default ComponentContext // connected to it, for the test to use to drive the CastRunner. @@ -64,36 +64,6 @@ void SetUp() override { ASSERT_TRUE(test_server_.Start()); } - zx::channel StartCastComponent( - const base::StringPiece& cast_url, - fidl::InterfaceRequest<fuchsia::sys::ComponentController> - component_controller_request) { - fuchsia::sys::LaunchInfo launch_info; - launch_info.url.reset(cast_url.as_string()); - - // Create a channel to pass to the Runner, through which to expose the new - // component's ServiceDirectory. - zx::channel service_directory_client; - zx_status_t status = zx::channel::create(0, &service_directory_client, - &launch_info.directory_request); - ZX_CHECK(status == ZX_OK, status) << "zx_channel_create"; - - fuchsia::sys::StartupInfo startup_info; - startup_info.launch_info = std::move(launch_info); - - // The FlatNamespace vectors must be non-null, but may be empty. - startup_info.flat_namespace.paths.resize(0); - startup_info.flat_namespace.directories.resize(0); - - fuchsia::sys::Package package; - package.resolved_url.reset(cast_url.as_string()); - - cast_runner_ptr_->StartComponent(std::move(package), - std::move(startup_info), - std::move(component_controller_request)); - return service_directory_client; - } - void RunUntilCastRunnerIsIdle() { until_runner_idle_loop_.Run(); } protected: @@ -125,30 +95,32 @@ std::unique_ptr<CastRunner> cast_runner_; fuchsia::sys::RunnerPtr cast_runner_ptr_; - DISALLOW_COPY_AND_ASSIGN(CastRunnerTest); + DISALLOW_COPY_AND_ASSIGN(CastRunnerUnitTest); }; -TEST_F(CastRunnerTest, TeardownOnClientUnbind) { +TEST_F(CastRunnerUnitTest, TeardownOnClientUnbind) { // Disconnect from the CastRunner and wait for it to terminate. cast_runner_ptr_.Unbind(); RunUntilCastRunnerIsIdle(); } -TEST_F(CastRunnerTest, TeardownOnComponentControllerUnbind) { +TEST_F(CastRunnerUnitTest, TeardownOnComponentControllerUnbind) { // Create a ComponentController pointer, to manage the component lifetime. fuchsia::sys::ComponentControllerPtr component_controller_ptr; // Launch the test-app component, passing a ComponentController request. - std::string url("cast:"); - url += castrunner::test::FakeApplicationConfigManager::kTestCastAppId; - base::fuchsia::ComponentContext component_services( - StartCastComponent(url, component_controller_ptr.NewRequest())); + base::fuchsia::ComponentContext component_services(StartCastComponent( + base::StringPrintf( + "cast:%s", + castrunner::test::FakeApplicationConfigManager::kTestCastAppId), + &cast_runner_ptr_, component_controller_ptr.NewRequest())); // Pump the message-loop to process StartComponent(). If the call is rejected // then the ComponentControllerPtr's error-handler will be invoked at this // point. component_controller_ptr.set_error_handler([](zx_status_t status) { - ZX_LOG(FATAL, status) << "Component launch failed"; + ZX_LOG(ERROR, status) << "Component launch failed"; + ADD_FAILURE(); }); base::RunLoop().RunUntilIdle();
diff --git a/webrunner/app/cast/test_common.cc b/webrunner/app/cast/test_common.cc new file mode 100644 index 0000000..1c8a663 --- /dev/null +++ b/webrunner/app/cast/test_common.cc
@@ -0,0 +1,41 @@ +// 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 "webrunner/app/cast/test_common.h" + +#include "base/fuchsia/fuchsia_logging.h" + +namespace castrunner { + +zx::channel StartCastComponent( + const base::StringPiece& cast_url, + fuchsia::sys::RunnerPtr* sys_runner, + fidl::InterfaceRequest<fuchsia::sys::ComponentController> + component_controller_request) { + fuchsia::sys::LaunchInfo launch_info; + launch_info.url.reset(cast_url.as_string()); + + // Create a channel to pass to the Runner, through which to expose the new + // component's ServiceDirectory. + zx::channel service_directory_client; + zx_status_t status = zx::channel::create(0, &service_directory_client, + &launch_info.directory_request); + ZX_CHECK(status == ZX_OK, status) << "zx_channel_create"; + + fuchsia::sys::StartupInfo startup_info; + startup_info.launch_info = std::move(launch_info); + + // The FlatNamespace vectors must be non-null, but may be empty. + startup_info.flat_namespace.paths.resize(0); + startup_info.flat_namespace.directories.resize(0); + + fuchsia::sys::Package package; + package.resolved_url.reset(cast_url.as_string()); + + sys_runner->get()->StartComponent(std::move(package), std::move(startup_info), + std::move(component_controller_request)); + return service_directory_client; +} + +} // namespace castrunner
diff --git a/webrunner/app/cast/test_common.h b/webrunner/app/cast/test_common.h new file mode 100644 index 0000000..daf93cd9 --- /dev/null +++ b/webrunner/app/cast/test_common.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 WEBRUNNER_APP_CAST_TEST_COMMON_H_ +#define WEBRUNNER_APP_CAST_TEST_COMMON_H_ + +#include <fuchsia/sys/cpp/fidl.h> + +#include "base/strings/string_piece.h" + +namespace castrunner { + +// Starts a cast component from the runner |sys_runner| with the URL |cast_url| +// and returns the service directory client channel. +zx::channel StartCastComponent( + const base::StringPiece& cast_url, + fuchsia::sys::RunnerPtr* sys_runner, + fidl::InterfaceRequest<fuchsia::sys::ComponentController> + component_controller_request); + +} // namespace castrunner + +#endif // WEBRUNNER_APP_CAST_TEST_COMMON_H_ \ No newline at end of file
diff --git a/webrunner/app/common/web_component.cc b/webrunner/app/common/web_component.cc index 19c3f8d..0c451c3cf 100644 --- a/webrunner/app/common/web_component.cc +++ b/webrunner/app/common/web_component.cc
@@ -33,7 +33,10 @@ DCHECK(url.is_valid()); std::unique_ptr<WebComponent> component(new WebComponent( runner, std::move(startup_info), std::move(controller_request))); - component->navigation_controller()->LoadUrl(url.spec(), nullptr); + chromium::web::NavigationControllerPtr navigation_controller; + component->frame()->GetNavigationController( + navigation_controller.NewRequest()); + navigation_controller->LoadUrl(url.spec(), nullptr); return component; } @@ -57,7 +60,6 @@ // Create the underlying Frame and get its NavigationController. runner_->context()->CreateFrame(frame_.NewRequest()); - frame_->GetNavigationController(navigation_controller_.NewRequest()); // Create a ServiceDirectory for this component, and publish a ViewProvider // into it, for the caller to use to create a View for this component.
diff --git a/webrunner/app/common/web_component.h b/webrunner/app/common/web_component.h index f345b867..b53681c 100644 --- a/webrunner/app/common/web_component.h +++ b/webrunner/app/common/web_component.h
@@ -44,6 +44,8 @@ fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller_request); + chromium::web::Frame* frame() { return frame_.get(); } + protected: // Creates a WebComponent encapsulating a web.Frame. A ViewProvider service // will be published to the service-directory specified in |startup_info|, and @@ -76,10 +78,6 @@ void DestroyComponent(int termination_exit_code, fuchsia::sys::TerminationReason reason); - chromium::web::Frame* frame() { return frame_.get(); } - chromium::web::NavigationController* navigation_controller() { - return navigation_controller_.get(); - } base::fuchsia::ServiceDirectory* service_directory() { return service_directory_.get(); } @@ -88,7 +86,6 @@ WebContentRunner* runner_ = nullptr; chromium::web::FramePtr frame_; - chromium::web::NavigationControllerPtr navigation_controller_; fidl::Binding<fuchsia::sys::ComponentController> controller_binding_;
diff --git a/webrunner/app/common/web_content_runner.cc b/webrunner/app/common/web_content_runner.cc index bc0e8dae..e24aaea2 100644 --- a/webrunner/app/common/web_content_runner.cc +++ b/webrunner/app/common/web_content_runner.cc
@@ -11,6 +11,7 @@ #include "base/files/file.h" #include "base/fuchsia/component_context.h" #include "base/fuchsia/file_utils.h" +#include "base/fuchsia/fuchsia_logging.h" #include "base/fuchsia/scoped_service_binding.h" #include "base/fuchsia/service_directory.h" #include "base/logging.h" @@ -40,7 +41,7 @@ web_context.set_error_handler([](zx_status_t status) { // If the browser instance died, then exit everything and do not attempt // to recover. appmgr will relaunch the runner when it is needed again. - LOG(ERROR) << "Connection to Context lost."; + ZX_LOG(ERROR, status) << "Connection to Context lost."; exit(1); }); return web_context; @@ -79,6 +80,15 @@ std::move(controller_request))); } +void WebContentRunner::GetWebComponentForTest( + base::OnceCallback<void(WebComponent*)> callback) { + if (!components_.empty()) { + std::move(callback).Run(components_.begin()->get()); + return; + } + web_component_test_callback_ = std::move(callback); +} + void WebContentRunner::DestroyComponent(WebComponent* component) { components_.erase(components_.find(component)); @@ -88,8 +98,12 @@ void WebContentRunner::RegisterComponent( std::unique_ptr<WebComponent> component) { - if (component) + if (web_component_test_callback_) { + std::move(web_component_test_callback_).Run(component.get()); + } + if (component) { components_.insert(std::move(component)); + } } void WebContentRunner::RunOnIdleClosureIfValid() {
diff --git a/webrunner/app/common/web_content_runner.h b/webrunner/app/common/web_content_runner.h index e2e54d4..df1499d 100644 --- a/webrunner/app/common/web_content_runner.h +++ b/webrunner/app/common/web_content_runner.h
@@ -53,6 +53,9 @@ fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller_request) override; + // Used by tests to asynchronously access the first WebComponent. + void GetWebComponentForTest(base::OnceCallback<void(WebComponent*)> callback); + protected: // Registers a WebComponent, or specialization, with this Runner. void RegisterComponent(std::unique_ptr<WebComponent> component); @@ -71,6 +74,9 @@ // disconnects, to quit the Runner. base::OnceClosure on_idle_closure_; + // Test-only callback for GetWebComponentForTest. + base::OnceCallback<void(WebComponent*)> web_component_test_callback_; + DISALLOW_COPY_AND_ASSIGN(WebContentRunner); };
diff --git a/webrunner/browser/frame_impl_browsertest.cc b/webrunner/browser/frame_impl_browsertest.cc index 1823d40..c3248fd 100644 --- a/webrunner/browser/frame_impl_browsertest.cc +++ b/webrunner/browser/frame_impl_browsertest.cc
@@ -21,6 +21,7 @@ #include "webrunner/common/test/test_common.h" #include "webrunner/common/test/webrunner_browser_test.h" #include "webrunner/service/common.h" +#include "webrunner/test/promise.h" namespace webrunner { @@ -739,7 +740,7 @@ message.data = MemBufferFromString(kPage1Path); Promise<bool> post_result; frame->PostMessage(std::move(message), post_message_url.GetOrigin().spec(), - post_result.GetReceiveCallback()); + ConvertToFitFunction(post_result.GetReceiveCallback())); base::RunLoop run_loop; EXPECT_CALL(navigation_observer_, MockableOnNavigationStateChanged( @@ -771,11 +772,12 @@ msg.data = MemBufferFromString("hi"); Promise<bool> post_result; frame->PostMessage(std::move(msg), post_message_url.GetOrigin().spec(), - post_result.GetReceiveCallback()); + ConvertToFitFunction(post_result.GetReceiveCallback())); base::RunLoop run_loop; Promise<chromium::web::WebMessage> receiver(run_loop.QuitClosure()); - message_port->ReceiveMessage(receiver.GetReceiveCallback()); + message_port->ReceiveMessage( + ConvertToFitFunction(receiver.GetReceiveCallback())); CheckRunWithTimeout(&run_loop); EXPECT_EQ("got_port", StringFromMemBufferOrDie(receiver->data)); } @@ -783,10 +785,12 @@ { msg.data = MemBufferFromString("ping"); Promise<bool> post_result; - message_port->PostMessage(std::move(msg), post_result.GetReceiveCallback()); + message_port->PostMessage( + std::move(msg), ConvertToFitFunction(post_result.GetReceiveCallback())); base::RunLoop run_loop; Promise<chromium::web::WebMessage> receiver(run_loop.QuitClosure()); - message_port->ReceiveMessage(receiver.GetReceiveCallback()); + message_port->ReceiveMessage( + ConvertToFitFunction(receiver.GetReceiveCallback())); CheckRunWithTimeout(&run_loop); EXPECT_EQ("ack ping", StringFromMemBufferOrDie(receiver->data)); EXPECT_TRUE(*post_result); @@ -814,11 +818,12 @@ msg.data = MemBufferFromString("hi"); Promise<bool> post_result; frame->PostMessage(std::move(msg), post_message_url.GetOrigin().spec(), - post_result.GetReceiveCallback()); + ConvertToFitFunction(post_result.GetReceiveCallback())); base::RunLoop run_loop; Promise<chromium::web::WebMessage> receiver(run_loop.QuitClosure()); - message_port->ReceiveMessage(receiver.GetReceiveCallback()); + message_port->ReceiveMessage( + ConvertToFitFunction(receiver.GetReceiveCallback())); CheckRunWithTimeout(&run_loop); EXPECT_EQ("got_port", StringFromMemBufferOrDie(receiver->data)); EXPECT_TRUE(*post_result); @@ -857,11 +862,13 @@ msg.outgoing_transfer->set_message_port(message_port.NewRequest()); msg.data = MemBufferFromString("hi"); Promise<bool> post_result; - frame->PostMessage(std::move(msg), "*", post_result.GetReceiveCallback()); + frame->PostMessage(std::move(msg), "*", + ConvertToFitFunction(post_result.GetReceiveCallback())); base::RunLoop run_loop; Promise<chromium::web::WebMessage> receiver(run_loop.QuitClosure()); - message_port->ReceiveMessage(receiver.GetReceiveCallback()); + message_port->ReceiveMessage( + ConvertToFitFunction(receiver.GetReceiveCallback())); CheckRunWithTimeout(&run_loop); EXPECT_EQ("got_port", StringFromMemBufferOrDie(receiver->data)); incoming_message_port = receiver->incoming_transfer->message_port().Bind(); @@ -874,8 +881,8 @@ base::RunLoop run_loop; Promise<bool> post_result(run_loop.QuitClosure()); msg.data = MemBufferFromString("ping"); - incoming_message_port->PostMessage(std::move(msg), - post_result.GetReceiveCallback()); + incoming_message_port->PostMessage( + std::move(msg), ConvertToFitFunction(post_result.GetReceiveCallback())); run_loop.Run(); EXPECT_TRUE(*post_result); } @@ -893,10 +900,12 @@ // Quit the runloop only after we've received a WebMessage AND a PostMessage // result. Promise<bool> post_result; - frame->PostMessage(std::move(msg), "*", post_result.GetReceiveCallback()); + frame->PostMessage(std::move(msg), "*", + ConvertToFitFunction(post_result.GetReceiveCallback())); base::RunLoop run_loop; Promise<chromium::web::WebMessage> receiver(run_loop.QuitClosure()); - ack_message_port->ReceiveMessage(receiver.GetReceiveCallback()); + ack_message_port->ReceiveMessage( + ConvertToFitFunction(receiver.GetReceiveCallback())); CheckRunWithTimeout(&run_loop); EXPECT_EQ("got_port", StringFromMemBufferOrDie(receiver->data)); EXPECT_TRUE(*post_result); @@ -906,7 +915,8 @@ for (int i = 0; i < 3; ++i) { base::RunLoop run_loop; Promise<chromium::web::WebMessage> receiver(run_loop.QuitClosure()); - incoming_message_port->ReceiveMessage(receiver.GetReceiveCallback()); + incoming_message_port->ReceiveMessage( + ConvertToFitFunction(receiver.GetReceiveCallback())); CheckRunWithTimeout(&run_loop); EXPECT_EQ("ack ping", StringFromMemBufferOrDie(receiver->data)); } @@ -933,11 +943,12 @@ msg.outgoing_transfer->set_message_port(unused_message_port.NewRequest()); msg.data = MemBufferFromString("bad origin, bad!"); Promise<bool> unused_post_result; - frame->PostMessage(std::move(msg), "https://example.com", - unused_post_result.GetReceiveCallback()); + frame->PostMessage( + std::move(msg), "https://example.com", + ConvertToFitFunction(unused_post_result.GetReceiveCallback())); Promise<chromium::web::WebMessage> unused_message_read; bad_origin_incoming_message_port->ReceiveMessage( - unused_message_read.GetReceiveCallback()); + ConvertToFitFunction(unused_message_read.GetReceiveCallback())); // PostMessage() with a valid origin should succeed. // Verify it by looking for an ack message on the MessagePort we passed in. @@ -951,10 +962,12 @@ msg.outgoing_transfer->set_message_port(message_port.NewRequest()); msg.data = MemBufferFromString("good origin"); Promise<bool> post_result; - frame->PostMessage(std::move(msg), "*", post_result.GetReceiveCallback()); + frame->PostMessage(std::move(msg), "*", + ConvertToFitFunction(post_result.GetReceiveCallback())); base::RunLoop run_loop; Promise<chromium::web::WebMessage> receiver(run_loop.QuitClosure()); - message_port->ReceiveMessage(receiver.GetReceiveCallback()); + message_port->ReceiveMessage( + ConvertToFitFunction(receiver.GetReceiveCallback())); CheckRunWithTimeout(&run_loop); EXPECT_EQ("got_port", StringFromMemBufferOrDie(receiver->data)); incoming_message_port = receiver->incoming_transfer->message_port().Bind();
diff --git a/webrunner/common/named_message_port_connector_browsertest.cc b/webrunner/common/named_message_port_connector_browsertest.cc index b10d9de..d0eefdf 100644 --- a/webrunner/common/named_message_port_connector_browsertest.cc +++ b/webrunner/common/named_message_port_connector_browsertest.cc
@@ -17,6 +17,7 @@ #include "webrunner/common/test/run_with_timeout.h" #include "webrunner/common/test/test_common.h" #include "webrunner/common/test/webrunner_browser_test.h" +#include "webrunner/test/promise.h" namespace webrunner { @@ -90,13 +91,16 @@ msg.data = MemBufferFromString("ping"); Promise<bool> post_result; (*message_port) - ->PostMessage(std::move(msg), post_result.GetReceiveCallback()); + ->PostMessage(std::move(msg), + ConvertToFitFunction(post_result.GetReceiveCallback())); std::vector<std::string> test_messages = {"early 1", "early 2", "ack ping"}; for (std::string expected_msg : test_messages) { base::RunLoop run_loop; Promise<chromium::web::WebMessage> message_receiver(run_loop.QuitClosure()); - (*message_port)->ReceiveMessage(message_receiver.GetReceiveCallback()); + (*message_port) + ->ReceiveMessage( + ConvertToFitFunction(message_receiver.GetReceiveCallback())); CheckRunWithTimeout(&run_loop); EXPECT_EQ(StringFromMemBufferOrDie(message_receiver->data), expected_msg); }
diff --git a/webrunner/common/test/test_common.h b/webrunner/common/test/test_common.h index 100b483d868..852c1a6 100644 --- a/webrunner/common/test/test_common.h +++ b/webrunner/common/test/test_common.h
@@ -48,51 +48,6 @@ DISALLOW_COPY_AND_ASSIGN(MockNavigationObserver); }; -// Stores an asynchronously generated value for later retrieval, optionally -// invoking a callback on value receipt for controlling test flow. -// -// The value can be read by using the dereference (*) or arrow (->) operators. -// Values must first be received before they can be accessed. Dereferencing a -// value before it is set will produce a CHECK violation. -template <typename T> -class Promise { - public: - explicit Promise(base::RepeatingClosure on_capture = base::DoNothing()) - : on_capture_(std::move(on_capture)) {} - - Promise(Promise&& other) = default; - - ~Promise() = default; - - // Returns a fit::function<> which will receive and store a value T. - fit::function<void(T)> GetReceiveCallback() { - return [this](T value) { ReceiveValue(std::move(value)); }; - } - - void ReceiveValue(T value) { - captured_ = std::move(value); - on_capture_.Run(); - } - - bool has_value() const { return captured_.has_value(); } - - T& operator*() { - CHECK(captured_.has_value()); - return *captured_; - } - - T* operator->() { - CHECK(captured_.has_value()); - return &*captured_; - } - - private: - base::Optional<T> captured_; - base::RepeatingClosure on_capture_; - - DISALLOW_COPY_AND_ASSIGN(Promise<T>); -}; - // Reads the contents of |buffer| in a std::string. std::string StringFromMemBufferOrDie(const fuchsia::mem::Buffer& buffer);
diff --git a/webrunner/test/promise.h b/webrunner/test/promise.h new file mode 100644 index 0000000..557c1107 --- /dev/null +++ b/webrunner/test/promise.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. + +#ifndef WEBRUNNER_TEST_PROMISE_H_ +#define WEBRUNNER_TEST_PROMISE_H_ + +#include "base/bind_helpers.h" +#include "base/optional.h" + +namespace webrunner { + +// Stores an asynchronously generated value for later retrieval, optionally +// invoking a callback on value receipt for controlling test flow. +// +// The value can be read by using the dereference (*) or arrow (->) operators. +// Values must first be received before they can be accessed. Dereferencing a +// value before it is set will produce a CHECK violation. +template <typename T> +class Promise { + public: + explicit Promise(base::RepeatingClosure on_capture = base::DoNothing()) + : on_capture_(std::move(on_capture)) {} + + Promise(Promise&& other) = default; + + ~Promise() = default; + + // Returns a OnceCallback which will receive and store a value T. + base::OnceCallback<void(T)> GetReceiveCallback() { + return base::BindOnce(&Promise<T>::ReceiveValue, base::Unretained(this)); + } + + void ReceiveValue(T value) { + captured_ = std::move(value); + on_capture_.Run(); + } + + bool has_value() const { return captured_.has_value(); } + + T& operator*() { + CHECK(captured_.has_value()); + return *captured_; + } + + T* operator->() { + CHECK(captured_.has_value()); + return &*captured_; + } + + private: + base::Optional<T> captured_; + base::RepeatingClosure on_capture_; + + DISALLOW_COPY_AND_ASSIGN(Promise<T>); +}; + +// Converts a Chromium OnceCallback to a fit::function. +template <typename TRet, typename... TArgs> +fit::function<TRet(TArgs...)> ConvertToFitFunction( + base::OnceCallback<TRet(TArgs...)> callback) { + return [callback = std::move(callback)](TArgs... args) mutable { + std::move(callback).Run(std::forward<TArgs>(args)...); + }; +} + +} // namespace webrunner + +#endif // WEBRUNNER_TEST_PROMISE_H_ \ No newline at end of file